Ejemplo n.º 1
0
    def __init__(self,
                 root=None,
                 handler=None,
                 src=None,
                 command=-1,
                 config=None,
                 requirements=None):
        """
		@param requirements: Details about the program we want to run
		@type requirements: L{requirements.Requirements}
		@param config: The configuration settings to use, or None to load from disk.
		@type config: L{config.Config}
		Note: all other arguments are deprecated (since 0launch 0.52)
		"""
        if requirements is None:
            from zeroinstall.injector.requirements import Requirements
            requirements = Requirements(root)
            requirements.source = bool(
                src)  # Root impl must be a "src" machine type
            if command == -1:
                if src:
                    command = 'compile'
                else:
                    command = 'run'
            requirements.command = command
        else:
            assert root == src == None
            assert command == -1

        if config is None:
            config = load_config(handler)
        else:
            assert handler is None, "can't pass a handler and a config"

        self.driver = driver.Driver(config=config, requirements=requirements)
Ejemplo n.º 2
0
	def __init__(self, root = None, handler = None, src = None, command = -1, config = None, requirements = None):
		"""
		@param requirements: Details about the program we want to run
		@type requirements: L{requirements.Requirements}
		@param config: The configuration settings to use, or None to load from disk.
		@type config: L{config.Config}
		Note: all other arguments are deprecated (since 0launch 0.52)
		"""
		if requirements is None:
			from zeroinstall.injector.requirements import Requirements
			requirements = Requirements(root)
			requirements.source = bool(src)				# Root impl must be a "src" machine type
			if command == -1:
				if src:
					command = 'compile'
				else:
					command = 'run'
			requirements.command = command
		else:
			assert root == src == None
			assert command == -1

		if config is None:
			config = load_config(handler)
		else:
			assert handler is None, "can't pass a handler and a config"

		self.driver = driver.Driver(config = config, requirements = requirements)
Ejemplo n.º 3
0
	def testDetails(self):
		iface_cache = self.config.iface_cache
		s = solver.DefaultSolver(self.config)

		foo_binary_uri = 'http://foo/Binary.xml'
		foo = iface_cache.get_interface(foo_binary_uri)
		self.import_feed(foo_binary_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')

		r = Requirements('http://foo/Binary.xml')
		r.source = True
		r.command = 'compile'

		s.record_details = True
		s.solve_for(r)
		assert s.ready, s.get_failure_reason()

		foo_bin_impls = iface_cache.get_feed(foo_binary_uri).implementations
		foo_src_impls = iface_cache.get_feed(foo_src.uri).implementations
		foo_impls = iface_cache.get_feed(foo.uri).implementations
		compiler_impls = iface_cache.get_feed(compiler.uri).implementations

		assert len(s.details) == 2
		self.assertEqual([
				(foo_src_impls['impossible'], None),
				(foo_src_impls['sha1=234'], None),
				(foo_impls['sha1=123'], 'Not source code'),
				(foo_src_impls['old'], None),
			], sorted(s.details[foo]))
		self.assertEqual([
				(compiler_impls['sha1=999'], None),
				(compiler_impls['sha1=345'], None),
				(compiler_impls['sha1=678'], None),
			], s.details[compiler])

		def justify(uri, impl, expected):
			iface = iface_cache.get_interface(uri)
			e = s.justify_decision(r, iface, impl)
			self.assertEqual(expected, e)

		justify(foo_binary_uri, foo_bin_impls["sha1=123"],
				'Binary 1.0 cannot be used (regardless of other components): Not source code')
		justify(foo_binary_uri, foo_src_impls["sha1=234"],
				'Binary 1.0 was selected as the preferred version.')
		justify(foo_binary_uri, foo_src_impls["old"],
				'Binary 0.1 is ranked lower than 1.0: newer versions are preferred')
		justify(foo_binary_uri, foo_src_impls["impossible"],
				"There is no possible selection using Binary 3.\n"
				"Can't find all required implementations:\n"
				"- http://foo/Binary.xml -> 3 (impossible)\n"
				"    User requested implementation 3 (impossible)\n"
				"- http://foo/Compiler.xml -> (problem)\n"
				"    http://foo/Binary.xml 3 requires version < 1.0, 1.0 <= version\n"
				"    No usable implementations satisfy the restrictions")
		justify(compiler.uri, compiler_impls["sha1=999"],
				'''Compiler 5 is selectable, but using it would produce a less optimal solution overall.\n\nThe changes would be:\n\nhttp://foo/Binary.xml: 1.0 to 0.1''')
Ejemplo n.º 4
0
	def __init__(self, root = None, handler = None, src = None, command = -1, config = None, requirements = None):
		"""
		@param requirements: Details about the program we want to run
		@type requirements: L{requirements.Requirements}
		@param config: The configuration settings to use, or None to load from disk.
		@type config: L{ConfigParser.ConfigParser}
		Note: all other arguments are deprecated (since 0launch 0.52)
		"""
		self.watchers = []
		if requirements is None:
			from zeroinstall.injector.requirements import Requirements
			requirements = Requirements(root)
			requirements.source = bool(src)				# Root impl must be a "src" machine type
			if command == -1:
				if src:
					command = 'compile'
				else:
					command = 'run'
			requirements.command = command
			self.target_arch = arch.get_host_architecture()
		else:
			assert root == src == None
			assert command == -1
			self.target_arch = arch.get_architecture(requirements.os, requirements.cpu)
		self.requirements = requirements

		self.stale_feeds = set()

		if config is None:
			self.config = load_config(handler or Handler())
		else:
			assert handler is None, "can't pass a handler and a config"
			self.config = config

		from zeroinstall.injector.solver import DefaultSolver
		self.solver = DefaultSolver(self.config)

		# If we need to download something but can't because we are offline,
		# warn the user. But only the first time.
		self._warned_offline = False

		debug(_("Supported systems: '%s'"), arch.os_ranks)
		debug(_("Supported processors: '%s'"), arch.machine_ranks)

		if requirements.before or requirements.not_before:
			self.solver.extra_restrictions[config.iface_cache.get_interface(requirements.interface_uri)] = [
					model.VersionRangeRestriction(model.parse_version(requirements.before),
								      model.parse_version(requirements.not_before))]
Ejemplo n.º 5
0
    def testArchFor(self):
        s = solver.DefaultSolver(self.config)
        r = Requirements('http://foo/Binary.xml')

        r.cpu = 'i386'
        bin_arch = s.get_arch_for(r)
        self.assertEqual({'i386': 0, None: 1}, bin_arch.machine_ranks)

        r.source = True
        src_arch = s.get_arch_for(r)
        self.assertEqual({'src': 1}, src_arch.machine_ranks)

        child = self.config.iface_cache.get_interface('http://foo/Dep.xml')
        arch = s.get_arch_for(r, child)
        self.assertEqual(arch.machine_ranks, bin_arch.machine_ranks)

        child = self.config.iface_cache.get_interface(r.interface_uri)
        arch = s.get_arch_for(r, child)
        self.assertEqual(arch.machine_ranks, src_arch.machine_ranks)
Ejemplo n.º 6
0
	def testArchFor(self):
		s = solver.DefaultSolver(self.config)
		r = Requirements('http://foo/Binary.xml')

		r.cpu = 'i386'
		bin_arch = s.get_arch_for(r)
		self.assertEqual({'i386': 0, None: 1}, bin_arch.machine_ranks)

		r.source = True
		src_arch = s.get_arch_for(r)
		self.assertEqual({'src': 1}, src_arch.machine_ranks)

		child = self.config.iface_cache.get_interface('http://foo/Dep.xml')
		arch = s.get_arch_for(r, child)
		self.assertEqual(arch.machine_ranks, bin_arch.machine_ranks)

		child = self.config.iface_cache.get_interface(r.interface_uri)
		arch = s.get_arch_for(r, child)
		self.assertEqual(arch.machine_ranks, src_arch.machine_ranks)
Ejemplo n.º 7
0
    def testDetails(self):
        iface_cache = self.config.iface_cache
        s = solver.DefaultSolver(self.config)

        foo_binary_uri = 'http://foo/Binary.xml'
        foo = iface_cache.get_interface(foo_binary_uri)
        self.import_feed(foo_binary_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')

        r = Requirements('http://foo/Binary.xml')
        r.source = True
        r.command = 'compile'

        s.record_details = True
        s.solve_for(r)
        assert s.ready, s.get_failure_reason()

        foo_bin_impls = iface_cache.get_feed(foo_binary_uri).implementations
        foo_src_impls = iface_cache.get_feed(foo_src.uri).implementations
        foo_impls = iface_cache.get_feed(foo.uri).implementations
        compiler_impls = iface_cache.get_feed(compiler.uri).implementations

        assert len(s.details) == 2
        self.assertEqual([
            (foo_src_impls['impossible'], None),
            (foo_src_impls['sha1=234'], None),
            (foo_impls['sha1=123'], 'Not source code'),
            (foo_src_impls['old'], None),
        ], sorted(s.details[foo]))
        self.assertEqual([
            (compiler_impls['sha1=999'], None),
            (compiler_impls['sha1=345'], None),
            (compiler_impls['sha1=678'], None),
        ], s.details[compiler])

        def justify(uri, impl, expected):
            iface = iface_cache.get_interface(uri)
            e = s.justify_decision(r, iface, impl)
            self.assertEqual(expected, e)

        self.maxDiff = 1000
        justify(
            foo_binary_uri, foo_bin_impls["sha1=123"],
            'Binary 1.0 cannot be used (regardless of other components): Not source code'
        )
        justify(foo_binary_uri, foo_src_impls["sha1=234"],
                'Binary 1.0 was selected as the preferred version.')
        justify(
            foo_binary_uri, foo_src_impls["old"],
            'Binary 0.1 is ranked lower than 1.0: newer versions are preferred'
        )
        justify(
            foo_binary_uri, foo_src_impls["impossible"],
            "There is no possible selection using Binary 3.\n"
            "Can't find all required implementations:\n"
            "- http://foo/Binary.xml -> 3 (impossible)\n"
            "    User requested implementation 3 (impossible)\n"
            "- http://foo/Compiler.xml -> (problem)\n"
            "    http://foo/Binary.xml 3 requires version < 1.0, 1.0 <= version\n"
            "    No usable implementations satisfy the restrictions:\n"
            "      sha1=999 (5): incompatible with restrictions\n"
            "      sha1=345 (1.0): incompatible with restrictions\n"
            "      sha1=678 (0.1): incompatible with restrictions")
        justify(
            compiler.uri, compiler_impls["sha1=999"],
            '''Compiler 5 is selectable, but using it would produce a less optimal solution overall.\n\nThe changes would be:\n\nhttp://foo/Binary.xml: 1.0 to 0.1'''
        )
Ejemplo n.º 8
0
	def testSelections(self):
		requirements = Requirements('http://foo/Source.xml')
		requirements.source = True
		requirements.command = 'compile'
		driver = Driver(requirements = requirements, config = self.config)
		source = self.config.iface_cache.get_interface('http://foo/Source.xml')
		compiler = self.config.iface_cache.get_interface('http://foo/Compiler.xml')
		self.import_feed(source.uri, 'Source.xml')
		self.import_feed(compiler.uri, 'Compiler.xml')

		self.config.network_use = model.network_full
		#import logging
		#logging.getLogger().setLevel(logging.DEBUG)
		assert driver.need_download()

		def assertSel(s):
			self.assertEqual('http://foo/Source.xml', s.interface)
			self.assertEqual(2, len(s.selections))

			sels = [(sel.interface, sel) for sel in s.selections.values()]
			sels.sort()
			sels = [sel for uri,sel in sels]
			
			self.assertEqual('http://foo/Compiler.xml', sels[0].interface)
			self.assertEqual('http://foo/Source.xml', sels[1].interface)

			self.assertEqual("sha1=345", sels[0].id)
			self.assertEqual("1.0", sels[0].version)

			self.assertEqual('sha1=234', sels[1].id)
			self.assertEqual("1.0", sels[1].version)
			self.assertEqual("bar", sels[1].attrs['http://namespace foo'])
			self.assertEqual("1.0", sels[1].attrs['version'])
			assert 'version-modifier' not in sels[1].attrs

			self.assertEqual(0, len(sels[0].bindings))
			self.assertEqual(0, len(sels[0].dependencies))

			self.assertEqual(3, len(sels[1].bindings))
			self.assertEqual('.', sels[1].bindings[0].insert)
			self.assertEqual('/', sels[1].bindings[1].mount_point)
			self.assertEqual('source', sels[1].bindings[2].qdom.attrs['foo'])

			self.assertEqual(1, len(sels[1].dependencies))
			dep = sels[1].dependencies[0]
			self.assertEqual('http://foo/Compiler.xml', dep.interface)
			self.assertEqual(4, len(dep.bindings))
			self.assertEqual('bin', dep.bindings[0].insert)
			self.assertEqual('PATH', dep.bindings[0].name)
			self.assertEqual('prepend', dep.bindings[0].mode)
			assert dep.bindings[0].separator in ';:'

			self.assertEqual('bin', dep.bindings[1].value)
			self.assertEqual('NO_PATH', dep.bindings[1].name)
			self.assertEqual(',', dep.bindings[1].separator)

			self.assertEqual('bin', dep.bindings[2].insert)
			self.assertEqual('BINDIR', dep.bindings[2].name)
			self.assertEqual('replace', dep.bindings[2].mode)

			foo_binding = dep.bindings[3]
			self.assertEqual('compiler', foo_binding.qdom.attrs['foo'])
			self.assertEqual('child', foo_binding.qdom.childNodes[0].name)
			self.assertEqual('run', foo_binding.command)

			self.assertEqual(["sha1=345", 'sha256new_345'], sorted(sels[0].digests))

		assert driver.solver.ready, driver.solver.get_failure_reason()
		s1 = driver.solver.selections
		s1.selections['http://foo/Source.xml'].attrs['http://namespace foo'] = 'bar'
		assertSel(s1)

		xml = s1.toDOM().toxml("utf-8")
		root = qdom.parse(BytesIO(xml))
		self.assertEqual(namespaces.XMLNS_IFACE, root.uri)

		s2 = selections.Selections(root)
		assertSel(s2)
Ejemplo n.º 9
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()
Ejemplo n.º 10
0
    def testSelections(self):
        requirements = Requirements('http://foo/Source.xml')
        requirements.source = True
        requirements.command = 'compile'
        driver = Driver(requirements=requirements, config=self.config)
        source = self.config.iface_cache.get_interface('http://foo/Source.xml')
        compiler = self.config.iface_cache.get_interface(
            'http://foo/Compiler.xml')
        self.import_feed(source.uri, 'Source.xml')
        self.import_feed(compiler.uri, 'Compiler.xml')

        self.config.network_use = model.network_full
        #import logging
        #logging.getLogger().setLevel(logging.DEBUG)
        assert driver.need_download()

        def assertSel(s):
            self.assertEqual('http://foo/Source.xml', s.interface)
            self.assertEqual(2, len(s.selections))

            sels = [(sel.interface, sel) for sel in s.selections.values()]
            sels.sort()
            sels = [sel for uri, sel in sels]

            self.assertEqual('http://foo/Compiler.xml', sels[0].interface)
            self.assertEqual('http://foo/Source.xml', sels[1].interface)

            self.assertEqual("sha1=345", sels[0].id)
            self.assertEqual("1.0", sels[0].version)

            self.assertEqual('sha1=234', sels[1].id)
            self.assertEqual("1.0", sels[1].version)
            self.assertEqual("bar", sels[1].attrs['http://namespace foo'])
            self.assertEqual("1.0", sels[1].attrs['version'])
            assert 'version-modifier' not in sels[1].attrs

            self.assertEqual(0, len(sels[0].bindings))
            self.assertEqual(0, len(sels[0].dependencies))

            self.assertEqual(3, len(sels[1].bindings))
            self.assertEqual('.', sels[1].bindings[0].insert)
            self.assertEqual('/', sels[1].bindings[1].mount_point)
            self.assertEqual('source', sels[1].bindings[2].qdom.attrs['foo'])

            self.assertEqual(1, len(sels[1].dependencies))
            dep = sels[1].dependencies[0]
            self.assertEqual('http://foo/Compiler.xml', dep.interface)
            self.assertEqual(4, len(dep.bindings))
            self.assertEqual('bin', dep.bindings[0].insert)
            self.assertEqual('PATH', dep.bindings[0].name)
            self.assertEqual('prepend', dep.bindings[0].mode)
            assert dep.bindings[0].separator in ';:'

            self.assertEqual('bin', dep.bindings[1].value)
            self.assertEqual('NO_PATH', dep.bindings[1].name)
            self.assertEqual(',', dep.bindings[1].separator)

            self.assertEqual('bin', dep.bindings[2].insert)
            self.assertEqual('BINDIR', dep.bindings[2].name)
            self.assertEqual('replace', dep.bindings[2].mode)

            foo_binding = dep.bindings[3]
            self.assertEqual('compiler', foo_binding.qdom.attrs['foo'])
            self.assertEqual('child', foo_binding.qdom.childNodes[0].name)
            self.assertEqual('run', foo_binding.command)

            self.assertEqual(["sha1=345", 'sha256new_345'],
                             sorted(sels[0].digests))

        assert driver.solver.ready, driver.solver.get_failure_reason()
        s1 = driver.solver.selections
        s1.selections['http://foo/Source.xml'].attrs[
            'http://namespace foo'] = 'bar'
        assertSel(s1)

        xml = s1.toDOM().toxml("utf-8")
        root = qdom.parse(BytesIO(xml))
        self.assertEqual(namespaces.XMLNS_IFACE, root.uri)

        s2 = selections.Selections(root)
        assertSel(s2)
Ejemplo n.º 11
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()