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-10-12 12:49:20 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2013-10-12 13:44:12 (GMT)
commitae6215c625a8f520e74ee513a38448b6a99d7c09 (patch)
treec2f871a672ac938e9d5ac5283ffacdce0085cc28
parent160d111f625ee3c896dad3aa026a630ecb5aa38b (diff)
While monitoring connectivity status, handle getting offline
-rw-r--r--sugar_network/client/routes.py30
-rw-r--r--sugar_network/toolkit/netlink.py2
-rw-r--r--tests/__init__.py8
-rwxr-xr-xtests/units/client/online_routes.py14
-rwxr-xr-xtests/units/client/routes.py12
-rwxr-xr-xtests/units/toolkit/options.py42
6 files changed, 70 insertions, 38 deletions
diff --git a/sugar_network/client/routes.py b/sugar_network/client/routes.py
index 42b1a36..0d869d0 100644
--- a/sugar_network/client/routes.py
+++ b/sugar_network/client/routes.py
@@ -124,8 +124,6 @@ class ClientRoutes(model.FrontRoutes, implementations.Routes, journal.Routes):
@route('GET', cmd='inline',
mime_type='application/json')
def inline(self):
- if not self._server_mode and not self._inline.is_set():
- self._remote_connect()
return self._inline.is_set()
def whoami(self, request, response):
@@ -229,20 +227,17 @@ class ClientRoutes(model.FrontRoutes, implementations.Routes, journal.Routes):
def _got_offline(self, force=False):
if not force and not self._inline.is_set():
return
- _logger.debug('Got offline on %r', self._node)
- self._node.close()
+ if self._node is not None:
+ _logger.debug('Got offline on %r', self._node)
+ self._node.close()
+ if self._inline.is_set():
+ self.broadcast({'event': 'inline', 'state': 'offline'})
self._inline.clear()
- self.broadcast({'event': 'inline', 'state': 'offline'})
self._local.volume.broadcast = self.broadcast
- def _fall_offline(self):
- if self._inline_job:
- _logger.debug('Fall to offline on %r', self._node)
- self._inline_job.kill()
-
def _restart_online(self):
- self._fall_offline()
- _logger.debug('Try to become online in %s seconds', _RECONNECT_TIMEOUT)
+ _logger.debug('Lost %r connection, try to reconnect in %s seconds',
+ self._node, _RECONNECT_TIMEOUT)
self._remote_connect(_RECONNECT_TIMEOUT)
def _discover_node(self):
@@ -253,10 +248,11 @@ class ClientRoutes(model.FrontRoutes, implementations.Routes, journal.Routes):
self._remote_connect()
def _wait_for_connectivity(self):
- for i in netlink.wait_for_route():
- self._fall_offline()
- if i:
+ for gw in netlink.wait_for_route():
+ if gw:
self._remote_connect()
+ else:
+ self._got_offline()
def _remote_connect(self, timeout=0):
@@ -306,8 +302,8 @@ class ClientRoutes(model.FrontRoutes, implementations.Routes, journal.Routes):
timeout *= _RECONNECT_TIMEOUT
timeout = min(timeout, _RECONNECT_TIMEOUT_MAX)
- if not self._inline_job:
- self._inline_job.spawn_later(timeout, connect)
+ self._inline_job.kill()
+ self._inline_job.spawn_later(timeout, connect)
def _found_mount(self, root):
if self._inline.is_set():
diff --git a/sugar_network/toolkit/netlink.py b/sugar_network/toolkit/netlink.py
index 0eb857a..9ad8370 100644
--- a/sugar_network/toolkit/netlink.py
+++ b/sugar_network/toolkit/netlink.py
@@ -66,7 +66,7 @@ def wait_for_route():
if not line:
break
dst, gw = line.split('\t', 3)[1:3]
- if int(dst, 16) == 0:
+ if int(dst, 16) in (0, 224):
return gw
old_route = get_route()
diff --git a/tests/__init__.py b/tests/__init__.py
index 7fd18d9..84df9b3 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -294,9 +294,9 @@ class Test(unittest.TestCase):
if classes is None:
classes = [User, Context, Implementation]
volume = db.Volume('client', classes)
- commands = routes(volume, client.api_url.value)
+ self.client_routes = routes(volume, client.api_url.value)
self.client = coroutine.WSGIServer(
- ('127.0.0.1', client.ipc_port.value), Router(commands))
+ ('127.0.0.1', client.ipc_port.value), Router(self.client_routes))
coroutine.spawn(self.client.serve_forever)
coroutine.dispatch()
return volume
@@ -316,8 +316,8 @@ class Test(unittest.TestCase):
def start_offline_client(self, resources=None):
self.home_volume = db.Volume('db', resources or model.RESOURCES)
- commands = ClientRoutes(self.home_volume)
- server = coroutine.WSGIServer(('127.0.0.1', client.ipc_port.value), Router(commands))
+ self.client_routes = ClientRoutes(self.home_volume)
+ server = coroutine.WSGIServer(('127.0.0.1', client.ipc_port.value), Router(self.client_routes))
coroutine.spawn(server.serve_forever)
coroutine.dispatch()
return IPCConnection()
diff --git a/tests/units/client/online_routes.py b/tests/units/client/online_routes.py
index d326223..6ad7484 100755
--- a/tests/units/client/online_routes.py
+++ b/tests/units/client/online_routes.py
@@ -1335,7 +1335,7 @@ Can't find all required implementations:
yield 'emote"'
node_pid = self.fork_master([User], NodeRoutes)
- ipc.get(cmd='inline')
+ self.client_routes._remote_connect()
self.wait_for_events(ipc, event='inline', state='online').wait()
ts = time.time()
@@ -1353,7 +1353,7 @@ Can't find all required implementations:
assert not ipc.get(cmd='inline')
node_pid = self.fork_master([User], NodeRoutes)
- ipc.get(cmd='inline')
+ self.client_routes._remote_connect()
self.wait_for_events(ipc, event='inline', state='online').wait()
coroutine.spawn(kill)
@@ -1361,7 +1361,7 @@ Can't find all required implementations:
assert not ipc.get(cmd='inline')
node_pid = self.fork_master([User], NodeRoutes)
- ipc.get(cmd='inline')
+ self.client_routes._remote_connect()
self.wait_for_events(ipc, event='inline', state='online').wait()
coroutine.spawn(kill)
@@ -1423,18 +1423,18 @@ Can't find all required implementations:
assert Routes.subscribe_tries > 2
def test_inline(self):
+ routes._RECONNECT_TIMEOUT = 2
+
cp = ClientRoutes(Volume('client', model.RESOURCES), client.api_url.value)
assert not cp.inline()
trigger = self.wait_for_events(cp, event='inline', state='online')
- coroutine.sleep(1)
+ coroutine.sleep(.5)
self.start_master()
- trigger.wait(1)
+ trigger.wait(.5)
assert trigger.value is None
assert not cp.inline()
- request = Request(method='GET', cmd='whoami')
- cp.whoami(request, Response())
trigger.wait()
assert cp.inline()
diff --git a/tests/units/client/routes.py b/tests/units/client/routes.py
index 6b0d6e5..53b1924 100755
--- a/tests/units/client/routes.py
+++ b/tests/units/client/routes.py
@@ -145,7 +145,7 @@ class RoutesTest(tests.Test):
trigger = self.wait_for_events(cp, event='inline', state='online')
node_volume = self.start_master()
- call(cp, Request(method='GET', cmd='inline'))
+ cp._remote_connect()
trigger.wait()
guid = call(cp, post)
@@ -169,7 +169,7 @@ class RoutesTest(tests.Test):
trigger = self.wait_for_events(cp, event='push')
self.start_master()
- call(cp, Request(method='GET', cmd='inline'))
+ cp._remote_connect()
trigger.wait()
self.assertEqual([[3, None]], json.load(file('client/push.sequence')))
@@ -198,7 +198,7 @@ class RoutesTest(tests.Test):
trigger = self.wait_for_events(cp, event='push')
self.start_master()
- call(cp, Request(method='GET', cmd='inline'))
+ cp._remote_connect()
trigger.wait()
self.assertEqual([[4, None]], json.load(file('client/push.sequence')))
@@ -227,7 +227,7 @@ class RoutesTest(tests.Test):
trigger = self.wait_for_events(cp, event='push')
self.start_master([User, Report])
- call(cp, Request(method='GET', cmd='inline'))
+ cp._remote_connect()
trigger.wait()
assert not volume['report'].exists(guid)
@@ -250,7 +250,7 @@ class RoutesTest(tests.Test):
trigger = self.wait_for_events(cp, event='push')
self.start_master()
- call(cp, Request(method='GET', cmd='inline'))
+ cp._remote_connect()
trigger.wait()
self.assertEqual([[2, None]], json.load(file('client/push.sequence')))
@@ -275,7 +275,7 @@ class RoutesTest(tests.Test):
trigger = self.wait_for_events(cp, event='inline', state='online')
self.start_master()
- call(cp, Request(method='GET', cmd='inline'))
+ cp._remote_connect()
trigger.wait()
assert not self.node_volume['context'].exists(guid)
diff --git a/tests/units/toolkit/options.py b/tests/units/toolkit/options.py
index 385c4da..1c5afa5 100755
--- a/tests/units/toolkit/options.py
+++ b/tests/units/toolkit/options.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
# sugar-lint: disable
+from ConfigParser import ConfigParser
+
from __init__ import tests
from sugar_network.toolkit import Option
@@ -33,14 +35,14 @@ class OptionsTest(tests.Test):
'[section]',
'option = 1',
]))
- Option.load(['config'])
+ Option.load(['./config'])
self.assertEqual('1', option.value)
option.value = '2'
Option.save()
option.value = ''
- Option.load(['config'])
+ Option.load(['./config'])
self.assertEqual('2', option.value)
def test_PreserveNonSeekConfigOnSave(self):
@@ -55,7 +57,7 @@ class OptionsTest(tests.Test):
'[bar]',
'o2 = 2 # bar',
]))
- Option.load(['config'])
+ Option.load(['./config'])
self.assertEqual('1', option.value)
option.value = '2'
@@ -74,6 +76,40 @@ class OptionsTest(tests.Test):
]),
file('config').read())
+ def test_SaveOnlyChangedOptions(self):
+ option1 = Option(name='option1', default='1')
+ option2 = Option(name='option2', default='2')
+ option3 = Option(name='option3', default='3')
+ Option.seek('section', [option1, option2, option3])
+ Option.load(['./config'])
+
+ self.assertEqual('1', option1.value)
+ self.assertEqual('2', option2.value)
+ self.assertEqual('3', option3.value)
+
+ Option.save()
+ parser = ConfigParser()
+ parser.read('config')
+ assert not parser.has_option('section', 'option1')
+ assert not parser.has_option('section', 'option2')
+ assert not parser.has_option('section', 'option3')
+
+ option1.value = '1_'
+ Option.save()
+ parser = ConfigParser()
+ parser.read('config')
+ self.assertEqual('1_', parser.get('section', 'option1'))
+ assert not parser.has_option('section', 'option2')
+ assert not parser.has_option('section', 'option3')
+
+ option2.value = '2_'
+ Option.save()
+ parser = ConfigParser()
+ parser.read('config')
+ self.assertEqual('1_', parser.get('section', 'option1'))
+ self.assertEqual('2_', parser.get('section', 'option2'))
+ assert not parser.has_option('section', 'option3')
+
if __name__ == '__main__':
tests.main()