Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2013-03-15 17:14:56 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2013-03-15 18:13:51 (GMT)
commit46b931c08946581486224c07ff2f49a0910a05d4 (patch)
tree0bef0bf990fab0e99592cadbe7f842e1e3b46095
parentc0fe0c6b16959aae8c94dba045e0d7f80ea8a350 (diff)
Polish design, move master related stuff from Context to node.master
-rw-r--r--sugar_network/client/clones.py2
-rw-r--r--sugar_network/client/spec.py3
-rw-r--r--sugar_network/db/document.py1
-rw-r--r--sugar_network/db/volume.py5
-rw-r--r--sugar_network/node/commands.py25
-rw-r--r--sugar_network/node/master.py75
-rw-r--r--sugar_network/node/slave.py2
-rw-r--r--sugar_network/resources/context.py54
-rw-r--r--tests/units/node/__main__.py1
-rwxr-xr-xtests/units/node/master.py210
-rwxr-xr-xtests/units/resources/context.py194
11 files changed, 291 insertions, 281 deletions
diff --git a/sugar_network/client/clones.py b/sugar_network/client/clones.py
index eb1943a..aedeb0f 100644
--- a/sugar_network/client/clones.py
+++ b/sugar_network/client/clones.py
@@ -134,7 +134,7 @@ class _Inotify(Inotify):
exception(_logger, 'Cannot read %r spec', clone_path)
return
- context = spec['Activity', 'implement']
+ context = spec['implement']
context_path = _context_path(context, hashed_path)
_ensure_path(context_path)
diff --git a/sugar_network/client/spec.py b/sugar_network/client/spec.py
index 544935e..ccbc787 100644
--- a/sugar_network/client/spec.py
+++ b/sugar_network/client/spec.py
@@ -29,6 +29,7 @@ _POLICY_URL = 'http://wiki.sugarlabs.org/go/Sugar_Network/Policy'
_FIELDS = {
# name: (required, typecast)
+ 'implement': (True, None),
'name': (True, None),
'summary': (True, None),
'description': (False, None),
@@ -119,7 +120,7 @@ class Spec(object):
return self._config.get(section, key)
def __repr__(self):
- return '<Spec %s>' % self['Activity', 'implement']
+ return '<Spec %s>' % self['implement']
def _get(self, section, key):
if self._config.has_option(section, key):
diff --git a/sugar_network/db/document.py b/sugar_network/db/document.py
index 66a1344..26f039b 100644
--- a/sugar_network/db/document.py
+++ b/sugar_network/db/document.py
@@ -32,6 +32,7 @@ class Document(object):
def __init__(self, guid, record, cached_props=None, request=None):
self.props = cached_props or {}
self.guid = guid
+ self.is_new = bool(guid)
self._record = record
self.request = request
diff --git a/sugar_network/db/volume.py b/sugar_network/db/volume.py
index 30eed62..0bbbeb8 100644
--- a/sugar_network/db/volume.py
+++ b/sugar_network/db/volume.py
@@ -228,6 +228,9 @@ class VolumeCommands(CommandsProcessor):
def before_update(self, request, props):
props['mtime'] = int(time.time())
+ def after_post(self, doc):
+ pass
+
@contextmanager
def _post(self, request, access):
enforce(isinstance(request.content, dict), 'Invalid value')
@@ -284,6 +287,8 @@ class VolumeCommands(CommandsProcessor):
directory.set_blob(doc.guid, name, value,
mime_type=request.content_type)
+ self.after_post(doc)
+
def _preget(self, request):
metadata = self.volume[request['document']].metadata
reply = request.setdefault('reply', [])
diff --git a/sugar_network/node/commands.py b/sugar_network/node/commands.py
index e43af1d..d964ca7 100644
--- a/sugar_network/node/commands.py
+++ b/sugar_network/node/commands.py
@@ -14,7 +14,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
-import re
import logging
import hashlib
from os.path import exists, join
@@ -26,18 +25,16 @@ from sugar_network.toolkit import router, util, coroutine, exception, enforce
_MAX_STATS_LENGTH = 100
-_GUID_RE = re.compile('[a-zA-Z0-9_+-.]+$')
_logger = logging.getLogger('node.commands')
class NodeCommands(db.VolumeCommands, Commands):
- def __init__(self, is_master, guid, volume):
+ def __init__(self, guid, volume):
db.VolumeCommands.__init__(self, volume)
Commands.__init__(self)
- self._is_master = is_master
self._guid = guid
self._stats = None
@@ -51,10 +48,6 @@ class NodeCommands(db.VolumeCommands, Commands):
def guid(self):
return self._guid
- @property
- def is_master(self):
- return self._is_master
-
@router.route('GET', '/packages')
def packages(self, request, response):
response.content_type = 'application/json'
@@ -86,10 +79,7 @@ class NodeCommands(db.VolumeCommands, Commands):
documents = {}
for name, directory in self.volume.items():
documents[name] = {'mtime': directory.mtime}
- return {'guid': self._guid,
- 'master': self._is_master,
- 'documents': documents,
- }
+ return {'guid': self._guid, 'documents': documents}
@db.volume_command(method='GET', cmd='stats',
mime_type='application/json', arguments={
@@ -278,17 +268,8 @@ class NodeCommands(db.VolumeCommands, Commands):
return cmd
def before_create(self, request, props):
- document = request['document']
- if document == 'user':
+ if request['document'] == 'user':
props['guid'], props['pubkey'] = _load_pubkey(props['pubkey'])
-
- if self._is_master and props.get('implement'):
- implement = props['implement'][0]
- enforce(not self.volume[document].exists(implement),
- 'Document already exists')
- enforce(_GUID_RE.match(implement) is not None, 'Malformed GUID')
- props['guid'] = implement
-
db.VolumeCommands.before_create(self, request, props)
@db.directory_command_pre(method='GET')
diff --git a/sugar_network/node/master.py b/sugar_network/node/master.py
index 460e798..acb1199 100644
--- a/sugar_network/node/master.py
+++ b/sugar_network/node/master.py
@@ -13,28 +13,29 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+import re
+import time
import json
import base64
import logging
-from urlparse import urlsplit
from Cookie import SimpleCookie
from os.path import join
-from sugar_network import db, client, node
-from sugar_network.node import sync, stats_user, files, volume, downloads
+from sugar_network import db, node
+from sugar_network.node import sync, stats_user, files, volume, downloads, obs
from sugar_network.node.commands import NodeCommands
-from sugar_network.toolkit import cachedir, util, enforce
+from sugar_network.toolkit import cachedir, coroutine, util, enforce
+_GUID_RE = re.compile('[a-zA-Z0-9_+-.]+$')
+
_logger = logging.getLogger('node.master')
class MasterCommands(NodeCommands):
- def __init__(self, volume_, guid=None):
- if not guid:
- guid = urlsplit(client.api_url.value).netloc
- NodeCommands.__init__(self, True, guid, volume_)
+ def __init__(self, guid, volume_):
+ NodeCommands.__init__(self, guid, volume_)
self._pulls = {
'pull': lambda **kwargs:
@@ -128,6 +129,28 @@ class MasterCommands(NodeCommands):
cookie.store(response)
return reply
+ def before_create(self, request, props):
+ implement = props.get('implement')
+ if implement:
+ implement = implement[0]
+ enforce(not self.volume[request['document']].exists(implement),
+ 'Document already exists')
+ enforce(_GUID_RE.match(implement) is not None, 'Malformed GUID')
+ props['guid'] = implement
+ NodeCommands.before_create(self, request, props)
+
+ def after_post(self, doc):
+ if doc.metadata.name == 'context':
+ shift_implementations = ('dependencies' in doc.props)
+ if 'aliases' in doc.props:
+ # TODO Already launched job should be killed
+ coroutine.spawn(self._resolve_aliases, doc)
+ shift_implementations = True
+ if shift_implementations and not doc.is_new:
+ # Shift mtime to invalidate solutions
+ self.volume['implementation'].mtime = int(time.time())
+ NodeCommands.after_post(self, doc)
+
def _push(self, stream):
reply = []
cookie = _Cookie()
@@ -160,6 +183,42 @@ class MasterCommands(NodeCommands):
return reply, cookie
+ def _resolve_aliases(self, doc):
+ packages = {}
+ for repo in obs.get_repos():
+ alias = doc['aliases'].get(repo['distributor_id'])
+ if not alias:
+ continue
+ package = packages[repo['name']] = {}
+ for kind in ('binary', 'devel'):
+ obs_fails = []
+ for to_resolve in alias.get(kind) or []:
+ if not to_resolve:
+ continue
+ try:
+ for arch in repo['arches']:
+ obs.resolve(repo['name'], arch, to_resolve)
+ except Exception, error:
+ _logger.warning('Failed to resolve %r on %s',
+ to_resolve, repo['name'])
+ obs_fails.append(str(error))
+ continue
+ package[kind] = to_resolve
+ break
+ else:
+ package['status'] = '; '.join(obs_fails)
+ break
+ else:
+ if 'binary' in package:
+ package['status'] = 'success'
+ else:
+ package['status'] = 'no packages to resolve'
+
+ if packages != doc['packages']:
+ doc.request.call('PUT', document='context', guid=doc.guid,
+ content={'packages': packages})
+ obs.presolve(doc['aliases'])
+
class _Cookie(list):
diff --git a/sugar_network/node/slave.py b/sugar_network/node/slave.py
index f25ccaf..aad36ed 100644
--- a/sugar_network/node/slave.py
+++ b/sugar_network/node/slave.py
@@ -38,7 +38,7 @@ _logger = logging.getLogger('node.slave')
class SlaveCommands(NodeCommands):
def __init__(self, guid, volume_):
- NodeCommands.__init__(self, False, guid, volume_)
+ NodeCommands.__init__(self, guid, volume_)
self._push_seq = util.PersistentSequence(
join(volume_.root, 'push.sequence'), [1, None])
diff --git a/sugar_network/resources/context.py b/sugar_network/resources/context.py
index 59a937e..433970b 100644
--- a/sugar_network/resources/context.py
+++ b/sugar_network/resources/context.py
@@ -13,14 +13,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import time
import logging
from os.path import join
from sugar_network import db, resources, static
from sugar_network.resources.volume import Resource
-from sugar_network.node import obs
-from sugar_network.toolkit import coroutine
_logger = logging.getLogger('resources.context')
@@ -136,63 +133,12 @@ class Context(Resource):
"""
return value
- @dependencies.setter
- def dependencies(self, value):
- if self.guid is not None or value:
- # Shift mtime to invalidate solutions
- self.volume['implementation'].mtime = int(time.time())
- return value
-
@db.stored_property(typecast=dict, default={},
permissions=db.ACCESS_PUBLIC | db.ACCESS_LOCAL)
def aliases(self, value):
return value
- @aliases.setter
- def aliases(self, value):
- coroutine.spawn(self._process_aliases, value)
- return value
-
@db.stored_property(typecast=dict, default={},
permissions=db.ACCESS_PUBLIC | db.ACCESS_LOCAL | db.ACCESS_SYSTEM)
def packages(self, value):
return value
-
- def _process_aliases(self, aliases):
- packages = {}
- for repo in obs.get_repos():
- alias = aliases.get(repo['distributor_id'])
- if not alias:
- continue
- package = packages[repo['name']] = {}
- for kind in ('binary', 'devel'):
- obs_fails = []
- for to_resolve in alias.get(kind) or []:
- if not to_resolve:
- continue
- try:
- for arch in repo['arches']:
- obs.resolve(repo['name'], arch, to_resolve)
- except Exception, error:
- _logger.warning('Failed to resolve %r on %s',
- to_resolve, repo['name'])
- obs_fails.append(str(error))
- continue
- package[kind] = to_resolve
- break
- else:
- package['status'] = '; '.join(obs_fails)
- break
- else:
- if 'binary' in package:
- package['status'] = 'success'
- else:
- package['status'] = 'no packages to resolve'
-
- if packages != self['packages']:
- self.request.call('PUT', document='context', guid=self.guid,
- content={'packages': packages})
- # Shift mtime to invalidate solutions
- self.volume['implementation'].mtime = int(time.time())
-
- obs.presolve(aliases)
diff --git a/tests/units/node/__main__.py b/tests/units/node/__main__.py
index 684e1b7..4ab7386 100644
--- a/tests/units/node/__main__.py
+++ b/tests/units/node/__main__.py
@@ -5,6 +5,7 @@ from __init__ import tests
from auth import *
from downloads import *
from files import *
+from master import *
from node import *
from obs import *
from stats_node import *
diff --git a/tests/units/node/master.py b/tests/units/node/master.py
new file mode 100755
index 0000000..ffdf8b0
--- /dev/null
+++ b/tests/units/node/master.py
@@ -0,0 +1,210 @@
+#!/usr/bin/env python
+# sugar-lint: disable
+
+from __init__ import tests
+
+from sugar_network.node import obs
+from sugar_network.client import IPCClient
+from sugar_network.toolkit import coroutine, enforce
+
+
+class MasterTest(tests.Test):
+
+ def test_Aliases(self):
+ self.override(obs, 'get_repos', lambda: [
+ {'distributor_id': 'Gentoo', 'name': 'Gentoo-2.1', 'arches': ['x86', 'x86_64']},
+ {'distributor_id': 'Debian', 'name': 'Debian-6.0', 'arches': ['x86']},
+ {'distributor_id': 'Debian', 'name': 'Debian-7.0', 'arches': ['x86_64']},
+ ])
+ self.override(obs, 'resolve', lambda repo, arch, names: ['fake'])
+ self.override(obs, 'presolve', lambda *args: None)
+
+ self.start_online_client()
+ ipc = IPCClient()
+
+ guid = ipc.post(['context'], {
+ 'type': 'activity',
+ 'title': 'title',
+ 'summary': 'summary',
+ 'description': 'description',
+ })
+
+ ipc.put(['context', guid, 'aliases'], {
+ 'Gentoo': {
+ 'binary': [['pkg1.bin', 'pkg2.bin']],
+ 'devel': [['pkg3.devel']],
+ },
+ 'Debian': {
+ 'binary': [['pkg4.bin']],
+ 'devel': [['pkg5.devel', 'pkg6.devel']],
+ },
+ })
+ coroutine.dispatch()
+ self.assertEqual({
+ 'Gentoo-2.1': {'status': 'success', 'binary': ['pkg1.bin', 'pkg2.bin'], 'devel': ['pkg3.devel']},
+ 'Debian-6.0': {'status': 'success', 'binary': ['pkg4.bin'], 'devel': ['pkg5.devel', 'pkg6.devel']},
+ 'Debian-7.0': {'status': 'success', 'binary': ['pkg4.bin'], 'devel': ['pkg5.devel', 'pkg6.devel']},
+ },
+ ipc.get(['context', guid, 'packages']))
+
+ def test_WrongAliases(self):
+ self.override(obs, 'get_repos', lambda: [
+ {'distributor_id': 'Gentoo', 'name': 'Gentoo-2.1', 'arches': ['x86', 'x86_64']},
+ {'distributor_id': 'Debian', 'name': 'Debian-6.0', 'arches': ['x86']},
+ {'distributor_id': 'Debian', 'name': 'Debian-7.0', 'arches': ['x86_64']},
+ ])
+ self.override(obs, 'resolve', lambda repo, arch, names: enforce(False, 'resolve failed'))
+ self.override(obs, 'presolve', lambda *args: None)
+
+ self.start_online_client()
+ ipc = IPCClient()
+
+ guid = ipc.post(['context'], {
+ 'type': 'activity',
+ 'title': 'title',
+ 'summary': 'summary',
+ 'description': 'description',
+ })
+
+ ipc.put(['context', guid, 'aliases'], {
+ 'Gentoo': {
+ 'binary': [['pkg1.bin', 'pkg2.bin']],
+ 'devel': [['pkg3.devel']],
+ },
+ 'Debian': {
+ 'binary': [['pkg4.bin']],
+ 'devel': [['pkg5.devel', 'pkg6.devel']],
+ },
+ })
+ coroutine.dispatch()
+ self.assertEqual({
+ 'Gentoo-2.1': {'status': 'resolve failed'},
+ 'Debian-6.0': {'status': 'resolve failed'},
+ 'Debian-7.0': {'status': 'resolve failed'},
+ },
+ ipc.get(['context', guid, 'packages']))
+
+ def test_MultipleAliases(self):
+
+ def resolve(repo, arch, names):
+ enforce(not [i for i in names if 'fake' in i], 'resolve failed')
+ return ['fake']
+
+ self.override(obs, 'get_repos', lambda: [
+ {'distributor_id': 'Gentoo', 'name': 'Gentoo-2.1', 'arches': ['x86', 'x86_64']},
+ ])
+ self.override(obs, 'resolve', resolve)
+ self.override(obs, 'presolve', lambda *args: None)
+
+ self.start_online_client()
+ ipc = IPCClient()
+
+ guid = ipc.post(['context'], {
+ 'type': 'activity',
+ 'title': 'title',
+ 'summary': 'summary',
+ 'description': 'description',
+ })
+
+ ipc.put(['context', guid, 'aliases'], {
+ 'Gentoo': {
+ 'binary': [['fake.bin'], ['proper.bin'], ['not-reach.bin']],
+ 'devel': [['fake.devel'], ['proper.devel'], ['not-reach.devel']],
+ },
+ })
+ coroutine.dispatch()
+ self.assertEqual({
+ 'Gentoo-2.1': {'status': 'success', 'binary': ['proper.bin'], 'devel': ['proper.devel']},
+ },
+ ipc.get(['context', guid, 'packages']))
+
+ ipc.put(['context', guid, 'aliases'], {
+ 'Gentoo': {
+ 'binary': [['proper.bin']],
+ 'devel': [['fake.devel']],
+ },
+ })
+ coroutine.dispatch()
+ self.assertEqual({
+ 'Gentoo-2.1': {'status': 'resolve failed', 'binary': ['proper.bin']},
+ },
+ ipc.get(['context', guid, 'packages']))
+
+ ipc.put(['context', guid, 'aliases'], {
+ 'Gentoo': {
+ 'binary': [['fake.bin']],
+ 'devel': [['proper.devel']],
+ },
+ })
+ coroutine.dispatch()
+ self.assertEqual({
+ 'Gentoo-2.1': {'status': 'resolve failed'},
+ },
+ ipc.get(['context', guid, 'packages']))
+
+ def test_InvalidateSolutions(self):
+ self.override(obs, 'get_repos', lambda: [
+ {'distributor_id': 'Gentoo', 'name': 'Gentoo-2.1', 'arches': ['x86_64']},
+ ])
+ self.override(obs, 'resolve', lambda repo, arch, names: ['fake'])
+ self.override(obs, 'presolve', lambda *args: None)
+
+ self.start_online_client()
+ ipc = IPCClient()
+
+ events = []
+ def read_events():
+ for event in ipc.subscribe():
+ if event.get('document') == 'implementation':
+ events.append(event)
+ job = coroutine.spawn(read_events)
+
+ guid = ipc.post(['context'], {
+ 'type': 'activity',
+ 'title': 'title',
+ 'summary': 'summary',
+ 'description': 'description',
+ })
+ ipc.put(['context', guid, 'aliases'], {
+ 'Gentoo': {
+ 'binary': [['bin']],
+ 'devel': [['devel']],
+ },
+ })
+ coroutine.dispatch()
+ self.assertEqual({
+ 'Gentoo-2.1': {'status': 'success', 'binary': ['bin'], 'devel': ['devel']},
+ },
+ ipc.get(['context', guid, 'packages']))
+ print events
+ self.assertEqual(1, len(events))
+ assert 'mtime' in events[0]['props']
+
+ def test_InvalidateSolutionsOnDependenciesChanges(self):
+ self.start_online_client()
+ ipc = IPCClient()
+
+ events = []
+ def read_events():
+ for event in ipc.subscribe():
+ if event.get('document') == 'implementation':
+ events.append(event)
+ job = coroutine.spawn(read_events)
+
+ guid = ipc.post(['context'], {
+ 'type': 'activity',
+ 'title': 'title',
+ 'summary': 'summary',
+ 'description': 'description',
+ 'dependencies': [],
+ })
+ self.assertEqual(0, len(events))
+
+ ipc.put(['context', guid, 'dependencies'], ['foo'])
+ self.assertEqual(1, len(events))
+ assert 'mtime' in events[0]['props']
+ del events[:]
+
+
+if __name__ == '__main__':
+ tests.main()
diff --git a/tests/units/resources/context.py b/tests/units/resources/context.py
index 6321798..7f61a5c 100755
--- a/tests/units/resources/context.py
+++ b/tests/units/resources/context.py
@@ -10,200 +10,6 @@ from sugar_network.toolkit import coroutine, enforce
class ContextTest(tests.Test):
- def test_Aliases(self):
- self.override(obs, 'get_repos', lambda: [
- {'distributor_id': 'Gentoo', 'name': 'Gentoo-2.1', 'arches': ['x86', 'x86_64']},
- {'distributor_id': 'Debian', 'name': 'Debian-6.0', 'arches': ['x86']},
- {'distributor_id': 'Debian', 'name': 'Debian-7.0', 'arches': ['x86_64']},
- ])
- self.override(obs, 'resolve', lambda repo, arch, names: ['fake'])
- self.override(obs, 'presolve', lambda: None)
-
- self.start_offline_client()
- client = IPCClient()
-
- guid = client.post(['context'], {
- 'type': 'activity',
- 'title': 'title',
- 'summary': 'summary',
- 'description': 'description',
- })
-
- client.put(['context', guid, 'aliases'], {
- 'Gentoo': {
- 'binary': [['pkg1.bin', 'pkg2.bin']],
- 'devel': [['pkg3.devel']],
- },
- 'Debian': {
- 'binary': [['pkg4.bin']],
- 'devel': [['pkg5.devel', 'pkg6.devel']],
- },
- })
- coroutine.dispatch()
- self.assertEqual({
- 'Gentoo-2.1': {'status': 'success', 'binary': ['pkg1.bin', 'pkg2.bin'], 'devel': ['pkg3.devel']},
- 'Debian-6.0': {'status': 'success', 'binary': ['pkg4.bin'], 'devel': ['pkg5.devel', 'pkg6.devel']},
- 'Debian-7.0': {'status': 'success', 'binary': ['pkg4.bin'], 'devel': ['pkg5.devel', 'pkg6.devel']},
- },
- client.get(['context', guid, 'packages']))
-
- def test_WrongAliases(self):
- self.override(obs, 'get_repos', lambda: [
- {'distributor_id': 'Gentoo', 'name': 'Gentoo-2.1', 'arches': ['x86', 'x86_64']},
- {'distributor_id': 'Debian', 'name': 'Debian-6.0', 'arches': ['x86']},
- {'distributor_id': 'Debian', 'name': 'Debian-7.0', 'arches': ['x86_64']},
- ])
- self.override(obs, 'resolve', lambda repo, arch, names: enforce(False, 'resolve failed'))
- self.override(obs, 'presolve', lambda: None)
-
- self.start_offline_client()
- client = IPCClient()
-
- guid = client.post(['context'], {
- 'type': 'activity',
- 'title': 'title',
- 'summary': 'summary',
- 'description': 'description',
- })
-
- client.put(['context', guid, 'aliases'], {
- 'Gentoo': {
- 'binary': [['pkg1.bin', 'pkg2.bin']],
- 'devel': [['pkg3.devel']],
- },
- 'Debian': {
- 'binary': [['pkg4.bin']],
- 'devel': [['pkg5.devel', 'pkg6.devel']],
- },
- })
- coroutine.dispatch()
- self.assertEqual({
- 'Gentoo-2.1': {'status': 'resolve failed'},
- 'Debian-6.0': {'status': 'resolve failed'},
- 'Debian-7.0': {'status': 'resolve failed'},
- },
- client.get(['context', guid, 'packages']))
-
- def test_MultipleAliases(self):
-
- def resolve(repo, arch, names):
- enforce(not [i for i in names if 'fake' in i], 'resolve failed')
- return ['fake']
-
- self.override(obs, 'get_repos', lambda: [
- {'distributor_id': 'Gentoo', 'name': 'Gentoo-2.1', 'arches': ['x86', 'x86_64']},
- ])
- self.override(obs, 'resolve', resolve)
- self.override(obs, 'presolve', lambda: None)
-
- self.start_offline_client()
- client = IPCClient()
-
- guid = client.post(['context'], {
- 'type': 'activity',
- 'title': 'title',
- 'summary': 'summary',
- 'description': 'description',
- })
-
- client.put(['context', guid, 'aliases'], {
- 'Gentoo': {
- 'binary': [['fake.bin'], ['proper.bin'], ['not-reach.bin']],
- 'devel': [['fake.devel'], ['proper.devel'], ['not-reach.devel']],
- },
- })
- coroutine.dispatch()
- self.assertEqual({
- 'Gentoo-2.1': {'status': 'success', 'binary': ['proper.bin'], 'devel': ['proper.devel']},
- },
- client.get(['context', guid, 'packages']))
-
- client.put(['context', guid, 'aliases'], {
- 'Gentoo': {
- 'binary': [['proper.bin']],
- 'devel': [['fake.devel']],
- },
- })
- coroutine.dispatch()
- self.assertEqual({
- 'Gentoo-2.1': {'status': 'resolve failed', 'binary': ['proper.bin']},
- },
- client.get(['context', guid, 'packages']))
-
- client.put(['context', guid, 'aliases'], {
- 'Gentoo': {
- 'binary': [['fake.bin']],
- 'devel': [['proper.devel']],
- },
- })
- coroutine.dispatch()
- self.assertEqual({
- 'Gentoo-2.1': {'status': 'resolve failed'},
- },
- client.get(['context', guid, 'packages']))
-
- def test_InvalidateSolutions(self):
- self.override(obs, 'get_repos', lambda: [
- {'distributor_id': 'Gentoo', 'name': 'Gentoo-2.1', 'arches': ['x86_64']},
- ])
- self.override(obs, 'resolve', lambda repo, arch, names: ['fake'])
- self.override(obs, 'presolve', lambda: None)
-
- self.start_offline_client()
- client = IPCClient()
-
- events = []
- def read_events():
- for event in client.subscribe():
- if event.get('document') == 'implementation':
- events.append(event)
- job = coroutine.spawn(read_events)
-
- guid = client.post(['context'], {
- 'type': 'activity',
- 'title': 'title',
- 'summary': 'summary',
- 'description': 'description',
- })
- client.put(['context', guid, 'aliases'], {
- 'Gentoo': {
- 'binary': [['bin']],
- 'devel': [['devel']],
- },
- })
- coroutine.dispatch()
- self.assertEqual({
- 'Gentoo-2.1': {'status': 'success', 'binary': ['bin'], 'devel': ['devel']},
- },
- client.get(['context', guid, 'packages']))
- self.assertEqual(1, len(events))
- assert 'mtime' in events[0]['props']
-
- def test_InvalidateSolutionsOnDependenciesChanges(self):
- self.start_offline_client()
- client = IPCClient()
-
- events = []
- def read_events():
- for event in client.subscribe():
- if event.get('document') == 'implementation':
- events.append(event)
- job = coroutine.spawn(read_events)
-
- guid = client.post(['context'], {
- 'type': 'activity',
- 'title': 'title',
- 'summary': 'summary',
- 'description': 'description',
- 'dependencies': [],
- })
- self.assertEqual(0, len(events))
-
- client.put(['context', guid, 'dependencies'], ['foo'])
- self.assertEqual(1, len(events))
- assert 'mtime' in events[0]['props']
- del events[:]
-
def test_SetCommonLayerForPackages(self):
self.start_offline_client()
ipc = IPCClient()