Made 0launch depend on Python explicitly
[zeroinstall/solver.git] / tests / basetest.py
blobef5610a61acbf7709f2fa5a743878b14c58c74ea
1 #!/usr/bin/env python
2 import sys, tempfile, os, shutil, StringIO
3 import unittest
4 import logging
5 import warnings
6 from xml.dom import minidom
7 warnings.filterwarnings("ignore", message = 'The CObject type')
9 # Catch silly mistakes...
10 os.environ['HOME'] = '/home/idontexist'
11 os.environ['LANGUAGE'] = 'C'
13 sys.path.insert(0, '..')
14 from zeroinstall.injector import qdom
15 from zeroinstall.injector import iface_cache, download, distro, model, handler, policy, reader, trust
16 from zeroinstall.zerostore import NotStored, Store, Stores; Store._add_with_helper = lambda *unused: False
17 from zeroinstall import support
18 from zeroinstall.support import basedir, tasks
20 dpkgdir = os.path.join(os.path.dirname(__file__), 'dpkg')
22 empty_feed = qdom.parse(StringIO.StringIO("""<interface xmlns='http://zero-install.sourceforge.net/2004/injector/interface'>
23 <name>Empty</name>
24 <summary>just for testing</summary>
25 </interface>"""))
27 import my_dbus
28 sys.modules['dbus'] = my_dbus
29 sys.modules['dbus.glib'] = my_dbus
30 my_dbus.types = my_dbus
31 sys.modules['dbus.types'] = my_dbus
32 sys.modules['dbus.mainloop'] = my_dbus
33 sys.modules['dbus.mainloop.glib'] = my_dbus
35 mydir = os.path.dirname(__file__)
37 # Catch us trying to run the GUI and return a dummy string instead
38 old_execvp = os.execvp
39 def test_execvp(prog, args):
40 if prog == sys.executable and args[1].endswith('/0launch-gui'):
41 prog = os.path.join(mydir, 'test-gui')
42 return old_execvp(prog, args)
44 os.execvp = test_execvp
46 test_locale = (None, None)
47 assert model.locale
48 class TestLocale:
49 LC_ALL = 'LC_ALL' # Note: LC_MESSAGES not present on Windows
50 def getlocale(self, x = None):
51 assert x is not TestLocale.LC_ALL
52 return test_locale
53 model.locale = TestLocale()
55 class DummyPackageKit:
56 available = False
58 def get_candidates(self, package, factory, prefix):
59 pass
61 class DummyHandler(handler.Handler):
62 __slots__ = ['ex', 'tb', 'allow_downloads']
64 def __init__(self):
65 handler.Handler.__init__(self)
66 self.ex = None
67 self.allow_downloads = False
69 def get_download(self, url, force = False, hint = None, factory = None):
70 if self.allow_downloads:
71 return handler.Handler.get_download(self, url, force, hint, factory)
72 raise model.SafeException("DummyHandler: " + url)
74 def wait_for_blocker(self, blocker):
75 self.ex = None
76 handler.Handler.wait_for_blocker(self, blocker)
77 if self.ex:
78 raise self.ex, None, self.tb
80 def report_error(self, ex, tb = None):
81 assert self.ex is None, self.ex
82 self.ex = ex
83 self.tb = tb
85 #import traceback
86 #traceback.print_exc()
88 class DummyKeyInfo:
89 def __init__(self, fpr):
90 self.fpr = fpr
91 self.info = [minidom.parseString('<item vote="bad"/>')]
92 self.blocker = None
94 class TestFetcher:
95 def __init__(self, config):
96 self.allowed_downloads = set()
97 self.allowed_feed_downloads = {}
98 self.config = config
100 def allow_download(self, digest):
101 assert isinstance(self.config.stores, TestStores)
102 self.allowed_downloads.add(digest)
104 def allow_feed_download(self, url, feed):
105 self.allowed_feed_downloads[url] = feed
107 def download_impls(self, impls, stores):
108 @tasks.async
109 def fake_download():
110 yield
111 for impl in impls:
112 assert impl.id in self.allowed_downloads, impl
113 self.allowed_downloads.remove(impl.id)
114 self.config.stores.add_fake(impl.id)
115 return fake_download()
117 def download_and_import_feed(self, feed_url, iface_cache, force = False):
118 @tasks.async
119 def fake_download():
120 yield
121 assert feed_url in self.allowed_feed_downloads, feed_url
122 self.config.iface_cache._feeds[feed_url] = self.allowed_feed_downloads[feed_url]
123 del self.allowed_feed_downloads[feed_url]
124 return fake_download()
126 def fetch_key_info(self, fingerprint):
127 return DummyKeyInfo(fingerprint)
129 class TestStores:
130 def __init__(self):
131 self.fake_impls = set()
133 def add_fake(self, digest):
134 self.fake_impls.add(digest)
136 def lookup_maybe(self, digests):
137 for d in digests:
138 if d in self.fake_impls:
139 return '/fake_store/' + d
140 return None
142 def lookup_any(self, digests):
143 path = self.lookup_maybe(digests)
144 if path:
145 return path
146 raise NotStored()
148 class TestConfig:
149 freshness = 0
150 help_with_testing = False
151 network_use = model.network_full
152 key_info_server = None
153 auto_approve_keys = False
155 def __init__(self):
156 self.iface_cache = iface_cache.IfaceCache()
157 self.handler = DummyHandler()
158 self.stores = Stores()
159 self.fetcher = TestFetcher(self)
160 self.trust_db = trust.trust_db
161 self.trust_mgr = trust.TrustMgr(self)
163 class BaseTest(unittest.TestCase):
164 def setUp(self):
165 warnings.resetwarnings()
167 self.config_home = tempfile.mktemp()
168 self.cache_home = tempfile.mktemp()
169 self.cache_system = tempfile.mktemp()
170 self.gnupg_home = tempfile.mktemp()
171 os.environ['GNUPGHOME'] = self.gnupg_home
172 os.environ['XDG_CONFIG_HOME'] = self.config_home
173 os.environ['XDG_CONFIG_DIRS'] = ''
174 os.environ['XDG_CACHE_HOME'] = self.cache_home
175 os.environ['XDG_CACHE_DIRS'] = self.cache_system
176 reload(basedir)
177 assert basedir.xdg_config_home == self.config_home
179 os.mkdir(self.config_home, 0700)
180 os.mkdir(self.cache_home, 0700)
181 os.mkdir(self.cache_system, 0500)
182 os.mkdir(self.gnupg_home, 0700)
184 if 'DISPLAY' in os.environ:
185 del os.environ['DISPLAY']
187 self.config = TestConfig()
188 policy._config = self.config # XXX
189 iface_cache.iface_cache = self.config.iface_cache
191 logging.getLogger().setLevel(logging.WARN)
193 download._downloads = {}
195 self.old_path = os.environ['PATH']
196 os.environ['PATH'] = dpkgdir + ':' + self.old_path
198 distro._host_distribution = distro.DebianDistribution(dpkgdir + '/status',
199 dpkgdir + '/pkgcache.bin')
200 distro._host_distribution._packagekit = DummyPackageKit()
202 my_dbus.system_services = {}
204 def tearDown(self):
205 assert self.config.handler.ex is None, self.config.handler.ex
207 shutil.rmtree(self.config_home)
208 support.ro_rmtree(self.cache_home)
209 shutil.rmtree(self.cache_system)
210 shutil.rmtree(self.gnupg_home)
212 os.environ['PATH'] = self.old_path
214 def import_feed(self, url, path):
215 iface_cache = self.config.iface_cache
216 iface_cache.get_interface(url)
217 feed = iface_cache._feeds[url] = reader.load_feed(path)
218 return feed