Repository: opensistemas-hub/osbrain
Pull request #108 (2017-03-31 11:45:10)

Fix bug affecting osmarkets
Now that osbrain uses IPC transport by default, osmarkets was failing because agents did not have a common path to store UNIX socket files. This pull request:

- Implements a common directory for UNIX socket files.
- Improves global configuration (use environment variables as expected)
- Increases minimum required Python version to 3.3 (main distributions already ship more recent Python versions). Python 3.4 will probably be unsupported too in the near future...


Patch:
diff --git a/.travis.yml b/.travis.yml
index c5b74cb..a8a2571 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,7 +4,6 @@ python:
   - 3.6
   - 3.5
   - 3.4.4
-  - 3.3
 
 install:
   - pip install tox tox-travis
diff --git a/docs/source/advanced_proxy_handling.rst b/docs/source/advanced_proxy_handling.rst
index 0836452..d7784bc 100644
--- a/docs/source/advanced_proxy_handling.rst
+++ b/docs/source/advanced_proxy_handling.rst
@@ -71,9 +71,11 @@ Or when creating a new :class:`Proxy <osbrain.proxy.Proxy>` to the agent:
 
    agent.method_call()  # This is now by default an unsafe method_call()
 
-It is also possible, although totally unadvisable, to change the default proxy
-behavior globally. Setting the ``OSBRAIN_DEFAULT_SAFE`` environment variable to
-``false`` would result in all proxies making unsafe calls by default.
+.. note:: It is also possible, although totally unadvisable, to change the
+   default proxy behavior globally. Setting the ``OSBRAIN_DEFAULT_SAFE``
+   environment variable to ``false`` would result in all proxies making unsafe
+   calls by default. Another option is to change the ``osbrain.config['SAFE']``
+   configuration variable.
 
 
 .. index:: proxy, oneway, concurrent
diff --git a/docs/source/serialization.rst b/docs/source/serialization.rst
index c259212..c3f6cdb 100644
--- a/docs/source/serialization.rst
+++ b/docs/source/serialization.rst
@@ -39,14 +39,15 @@ There are three ways in which the serializer can be specified:
 Global configuration
 ====================
 
-By setting the `OSBRAIN_DEFAULT_SERIALIZER` environment variable, we can set
-the default serializer between agents.
-
-For example, we could set it from our `.py` configuration file:
+By setting the ``osbrain.config['SERIALIZER']`` configuration variable, we
+can change the default serializer. For example:
 
 .. code:: python
 
-    os.environ['OSBRAIN_DEFAULT_SERIALIZER'] = 'json'
+    osbrain.config['SERIALIZER'] = 'json'
+
+.. note:: It is also possible to change the global default serializer by
+   setting the ``OSBRAIN_DEFAULT_SERIALIZER`` environment variable.
 
 
 Per agent configuration
diff --git a/docs/source/transport_protocol.rst b/docs/source/transport_protocol.rst
index 18738d7..d14cd23 100644
--- a/docs/source/transport_protocol.rst
+++ b/docs/source/transport_protocol.rst
@@ -19,7 +19,7 @@ protocols that can be used in osBrain:
   different machines.
 - ``ipc``: common `IPC <https://en.wikipedia.org/wiki/Inter-process_communication>`_. It is the default and the best suited for communication between agents that
   run on the same machine
-- ``inproc``: for in-process communication (between threads). The fastest 
+- ``inproc``: for in-process communication (between threads). The fastest
   protocol, although it is limited to communication between threads that share
   the same :attr:`Agent.context <osbrain.agent.Agent.context>`
 
@@ -33,12 +33,12 @@ Changing the transport
 ======================
 
 It is possible to change the default global transport protocol by setting
-the ``OSBRAIN_DEFAULT_TRANSPORT`` environment variable. So, for example, to
+the ``osbrain.config['TRANSPORT']`` configuration variable. So, for example, to
 set TCP as the default transport, we could set:
 
 .. code-block:: python
 
-   os.environ['OSBRAIN_DEFAULT_TRANSPORT'] = 'tcp'
+   osbrain.config['TRANSPORT'] = 'tcp'
 
 We can also set the default transport that a particular agent should use by
 default by passing the ``transport`` parameter to
@@ -56,3 +56,6 @@ we can still change the transport protocol when binding, passing the
 
    agent = run_agent('a0')
    agent.bind('PULL', transport='inproc')
+
+.. note:: It is also possible to change the global default transport protocol
+   setting the ``OSBRAIN_DEFAULT_TRANSPORT`` environment variable.
diff --git a/examples/explicit_serialization.py b/examples/explicit_serialization.py
index 81cd687..39fc86f 100644
--- a/examples/explicit_serialization.py
+++ b/examples/explicit_serialization.py
@@ -2,8 +2,7 @@
 A simple example in which the different serialization setting
 options are shown.
 '''
-import os
-
+import osbrain
 from osbrain import run_nameserver
 from osbrain import run_agent
 
@@ -15,7 +14,7 @@ def set_received(agent, message, topic=None):
 if __name__ == '__main__':
     # We can define the default serializer through environment variables.
     # This will be the preferred method from now on, unless overriden.
-    os.environ['OSBRAIN_DEFAULT_SERIALIZER'] = 'pickle'
+    osbrain.config['SERIALIZER'] = 'pickle'
 
     ns = run_nameserver()
 
diff --git a/osbrain/__init__.py b/osbrain/__init__.py
index 2dc1100..e2b55d4 100644
--- a/osbrain/__init__.py
+++ b/osbrain/__init__.py
@@ -1,4 +1,17 @@
 import os
+import sys
+from pathlib import Path
+
+# While Python 3.4 is supported...
+if sys.version_info < (3, 5):
+    def mkdir(directory, **kwargs):
+        directory = str(directory)
+        os.makedirs(directory, exist_ok=kwargs['exist_ok'])
+
+    from os.path import expanduser
+    Path.home = lambda: Path(expanduser('~'))
+    Path.mkdir = lambda directory, **kwargs: mkdir(directory, **kwargs)
+
 import Pyro4
 Pyro4.config.SERIALIZERS_ACCEPTED.add('pickle')
 Pyro4.config.SERIALIZERS_ACCEPTED.add('dill')
@@ -8,10 +21,18 @@ Pyro4.config.SERVERTYPE = 'thread'
 Pyro4.config.REQUIRE_EXPOSE = False
 Pyro4.config.COMMTIMEOUT = 0.
 Pyro4.config.DETAILED_TRACEBACK = True
-os.environ['OSBRAIN_DEFAULT_TRANSPORT'] = 'ipc'
-os.environ['OSBRAIN_DEFAULT_SAFE'] = 'true'
-os.environ['OSBRAIN_DEFAULT_SERIALIZER'] = 'pickle'
-os.environ['OSBRAIN_DEFAULT_LINGER'] = '1'
+
+config = {}
+config['SAFE'] = os.environ.get('OSBRAIN_DEFAULT_SAFE', 'true') != 'false'
+config['SERIALIZER'] = os.environ.get('OSBRAIN_DEFAULT_SERIALIZER', 'pickle')
+config['LINGER'] = float(os.environ.get('OSBRAIN_DEFAULT_LINGER', '1'))
+config['TRANSPORT'] = os.environ.get('OSBRAIN_DEFAULT_TRANSPORT', 'ipc')
+
+# Set storage folder for IPC socket files
+config['IPC_DIR'] = \
+    Path(os.environ.get('XDG_RUNTIME_DIR', Path.home())) / '.osbrain_ipc'
+config['IPC_DIR'].mkdir(exist_ok=True, parents=True)
+
 
 __version__ = '0.4.1'
 
diff --git a/osbrain/agent.py b/osbrain/agent.py
index dc23030..097aa7f 100644
--- a/osbrain/agent.py
+++ b/osbrain/agent.py
@@ -19,6 +19,7 @@ import Pyro4
 from Pyro4.errors import PyroError
 import zmq
 
+from . import config
 from .common import format_exception
 from .common import format_method_exception
 from .common import unbound_method
@@ -603,10 +604,10 @@ class Agent():
         kind = guess_kind(kind)
         transport = transport \
             or self.transport \
-            or os.environ.get('OSBRAIN_DEFAULT_TRANSPORT')
+            or config['TRANSPORT']
         serializer = serializer \
             or self.serializer \
-            or os.getenv('OSBRAIN_DEFAULT_SERIALIZER')
+            or config['SERIALIZER']
         if isinstance(kind, AgentAddressKind):
             return self._bind_address(kind, alias, handler, addr, transport,
                                       serializer)
@@ -732,6 +733,8 @@ class Agent():
         else:
             if not addr:
                 addr = str(uuid4())
+            if transport == 'ipc':
+                addr = config['IPC_DIR'] / addr
             socket.bind('%s://%s' % (transport, addr))
         return addr
 
diff --git a/osbrain/common.py b/osbrain/common.py
index b7a3e87..b5f1dcf 100644
--- a/osbrain/common.py
+++ b/osbrain/common.py
@@ -1,12 +1,13 @@
 """
 Miscellaneous utilities.
 """
-import os
 import time
 from threading import Event
 from threading import Thread
 import traceback
 
+from . import config
+
 
 def format_exception():
     """
@@ -136,8 +137,8 @@ def get_linger():
         Number of seconds to linger.
         Note that -1 means linger forever.
     """
-    value = os.getenv('OSBRAIN_DEFAULT_LINGER')
+    value = config['LINGER']
 
-    if value == '-1':
+    if value < 0:
         return -1
     return int(float(value) * 1000)
diff --git a/osbrain/proxy.py b/osbrain/proxy.py
index 5725aba..25bb9f5 100644
--- a/osbrain/proxy.py
+++ b/osbrain/proxy.py
@@ -4,8 +4,11 @@ Implementation of proxy-related features.
 import os
 import sys
 import time
+
 import Pyro4
 from Pyro4.errors import NamingError
+
+from . import config
 from .address import address_to_host_port
 from .address import SocketAddress
 
@@ -57,8 +60,8 @@ class Proxy(Pyro4.core.Proxy):
     timeout : float
         Timeout, in seconds, to wait until the agent is discovered.
     safe : bool, default is None
-        Use safe calls by default. When not set, environment's
-        OSBRAIN_DEFAULT_SAFE is used.
+        Use safe calls by default. When not set, osbrain default's
+        `osbrain.config['SAFE']` is used.
     """
     def __init__(self, name, nsaddr=None, timeout=3., safe=None):
         if not nsaddr:
@@ -71,8 +74,7 @@ class Proxy(Pyro4.core.Proxy):
         if safe is not None:
             self._default_safe = safe
         else:
-            self._default_safe = \
-                os.environ['OSBRAIN_DEFAULT_SAFE'].lower() != 'false'
+            self._default_safe = config['SAFE']
         self._safe = self._default_safe
         self._next_oneway = False
         while not self._ready_or_timeout(time0, timeout):
diff --git a/setup.py b/setup.py
index cb316ed..5776eaf 100644
--- a/setup.py
+++ b/setup.py
@@ -28,7 +28,6 @@ setup(
         'Topic :: Software Development :: Build Tools',
         'License :: OSI Approved :: Apache Software License',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.3',
         'Programming Language :: Python :: 3.4',
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
diff --git a/tox.ini b/tox.ini
index 0311bcb..498fcf5 100644
--- a/tox.ini
+++ b/tox.ini
@@ -5,7 +5,6 @@ envlist =
     py36
     py35
     py34
-    py33
 
 [testenv]
 deps =


Test patch:
diff --git a/osbrain/tests/test_agent.py b/osbrain/tests/test_agent.py
index 7d21f75..021afe0 100644
--- a/osbrain/tests/test_agent.py
+++ b/osbrain/tests/test_agent.py
@@ -1,22 +1,20 @@
 """
 Test file for agents.
 """
-import os
 import time
-import random
 from uuid import uuid4
 from threading import Timer
 
 import pytest
 import Pyro4
 
+import osbrain
 from osbrain import run_logger
 from osbrain import run_agent
 from osbrain import Agent
 from osbrain import AgentAddress
 from osbrain import AgentProcess
 from osbrain import Proxy
-from osbrain import SocketAddress
 from osbrain.helper import agent_dies
 from osbrain.helper import logger_received
 from osbrain.helper import sync_agent_logger
@@ -184,31 +182,13 @@ def test_socket_creation(nsproxy):
     assert a0.addr('alias2') == addr2
 
 
-@pytest.mark.parametrize('agent_serial,socket_serial,result', [
-    (None, None, os.getenv('OSBRAIN_DEFAULT_SERIALIZER')),
-    ('raw', None, 'raw'),
-    ('pickle', None, 'pickle'),
-    (None, 'raw', 'raw'),
-    (None, 'json', 'json'),
-    ('pickle', 'json', 'json'),
-])
-def test_correct_serialization(nsproxy, agent_serial, socket_serial, result):
-    """
-    Test that the right serializer is being used when using the different
-    initialization options.
-    """
-    agent = run_agent('a0', serializer=agent_serial)
-    addr = agent.bind('PUB', serializer=socket_serial)
-    assert addr.serializer == result
-
-
-@pytest.mark.parametrize('linger_ms, sleep_time, should_receive', [
+@pytest.mark.parametrize('linger, sleep_time, should_receive', [
     (2, 1, True),
     (0.5, 1, False),
     (0, 1, False),
     (-1, 1, True),
 ])
-def test_linger(nsproxy, linger_ms, sleep_time, should_receive):
+def test_linger(nsproxy, linger, sleep_time, should_receive):
     '''
     Test linger works when closing the sockets of an agent.
     '''
@@ -216,7 +196,7 @@ def test_linger(nsproxy, linger_ms, sleep_time, should_receive):
         def on_init(self):
             self.received = []
 
-    os.environ["OSBRAIN_DEFAULT_LINGER"] = str(linger_ms)
+    osbrain.config['LINGER'] = linger
 
     puller = run_agent('puller', base=AgentTest)
     pusher = run_agent('pusher', base=AgentTest)
@@ -556,76 +536,3 @@ def test_agent_stop(nsproxy):
     while agent.get_attr('running'):
         time.sleep(0.01)
     assert not agent.get_attr('running')
-
-
-def test_agent_bind_transport_global(nsproxy):
-    """
-    Test global default transport.
-    """
-    # Default transport
-    agent = run_agent('a0')
-    address = agent.bind('PUSH')
-    assert address.transport == 'ipc'
-
-    # Changing default global transport
-    os.environ['OSBRAIN_DEFAULT_TRANSPORT'] = 'tcp'
-    agent = run_agent('a1')
-    address = agent.bind('PUSH')
-    assert address.transport == 'tcp'
-
-    os.environ['OSBRAIN_DEFAULT_TRANSPORT'] = 'ipc'
-    agent = run_agent('a2')
-    address = agent.bind('PUSH')
-    assert address.transport == 'ipc'
-
-
-def test_agent_bind_transport_agent(nsproxy):
-    """
-    Test agent default transport.
-    """
-    agent = run_agent('a0', transport='tcp')
-    address = agent.bind('PUSH')
-    assert address.transport == 'tcp'
-
-    agent = run_agent('a1', transport='ipc')
-    address = agent.bind('PUSH')
-    assert address.transport == 'ipc'
-
-
-def test_agent_bind_transport_bind(nsproxy):
-    """
-    Test bind transport.
-    """
-    agent = run_agent('a0')
-
-    address = agent.bind('PUSH', transport='tcp')
-    assert address.transport == 'tcp'
-
-    address = agent.bind('PUSH', transport='inproc')
-    assert address.transport == 'inproc'
-
-
-def test_agent_bind_given_address(nsproxy):
-    """
-    Test agent binding to an specified address using TCP and IPC transport
-    layers.
-    """
-    agent = run_agent('a0')
-    # IPC
-    ipc_addr = str(uuid4())
-    address = agent.bind('PUSH', addr=ipc_addr, transport='ipc')
-    assert address.transport == 'ipc'
-    assert address.address == ipc_addr
-    # TCP
-    while True:
-        try:
-            # Bind to random port
-            port = random.randrange(10000, 20000)
-            tcp_addr = '127.0.0.1:%s' % port
-            tcp_addr = SocketAddress('127.0.0.1', port)
-            address = agent.bind('PUSH', addr=tcp_addr, transport='tcp')
-            break
-        except Exception:
-            pass
-    assert address.transport == 'tcp'
-    assert address.address == tcp_addr
diff --git a/osbrain/tests/test_agent_serialization.py b/osbrain/tests/test_agent_serialization.py
index a97f9e5..db3525c 100644
--- a/osbrain/tests/test_agent_serialization.py
+++ b/osbrain/tests/test_agent_serialization.py
@@ -5,6 +5,7 @@ import json
 import zmq
 import pytest
 
+import osbrain
 from osbrain import run_agent
 from osbrain.agent import serialize_message
 from osbrain.agent import deserialize_message
@@ -42,6 +43,24 @@ def test_message_composer():
         compose_message(message, topic, 'foo')
 
 
+@pytest.mark.parametrize('agent_serial,socket_serial,result', [
+    (None, None, osbrain.config['SERIALIZER']),
+    ('raw', None, 'raw'),
+    ('pickle', None, 'pickle'),
+    (None, 'raw', 'raw'),
+    (None, 'json', 'json'),
+    ('pickle', 'json', 'json'),
+])
+def test_correct_serialization(nsproxy, agent_serial, socket_serial, result):
+    """
+    Test that the right serializer is being used when using the different
+    initialization options.
+    """
+    agent = run_agent('a0', serializer=agent_serial)
+    addr = agent.bind('PUB', serializer=socket_serial)
+    assert addr.serializer == result
+
+
 def test_serialize_message():
     """
     Test basic serialization.
diff --git a/osbrain/tests/test_agent_transport.py b/osbrain/tests/test_agent_transport.py
new file mode 100644
index 0000000..092bb7f
--- /dev/null
+++ b/osbrain/tests/test_agent_transport.py
@@ -0,0 +1,130 @@
+"""
+Test file for communication transport.
+"""
+import os
+import random
+from shutil import rmtree
+from tempfile import mkdtemp
+from uuid import uuid4
+
+import osbrain
+from osbrain import Agent
+from osbrain import run_agent
+from osbrain import SocketAddress
+from osbrain.helper import wait_agent_attr
+
+from common import nsproxy  # pragma: no flakes
+
+
+def test_agent_bind_transport_global(nsproxy):
+    """
+    Test global default transport.
+    """
+    # Default transport
+    agent = run_agent('a0')
+    address = agent.bind('PUSH')
+    assert address.transport == 'ipc'
+
+    # Changing default global transport
+    osbrain.config['TRANSPORT'] = 'tcp'
+    agent = run_agent('a1')
+    address = agent.bind('PUSH')
+    assert address.transport == 'tcp'
+
+    osbrain.config['TRANSPORT'] = 'ipc'
+    agent = run_agent('a2')
+    address = agent.bind('PUSH')
+    assert address.transport == 'ipc'
+
+
+def test_agent_bind_transport_agent(nsproxy):
+    """
+    Test agent default transport.
+    """
+    agent = run_agent('a0', transport='tcp')
+    address = agent.bind('PUSH')
+    assert address.transport == 'tcp'
+
+    agent = run_agent('a1', transport='ipc')
+    address = agent.bind('PUSH')
+    assert address.transport == 'ipc'
+
+
+def test_agent_bind_transport_bind(nsproxy):
+    """
+    Test bind transport.
+    """
+    agent = run_agent('a0')
+
+    address = agent.bind('PUSH', transport='tcp')
+    assert address.transport == 'tcp'
+
+    address = agent.bind('PUSH', transport='inproc')
+    assert address.transport == 'inproc'
+
+
+def test_agent_bind_given_address(nsproxy):
+    """
+    Test agent binding to an specified address using TCP and IPC transport
+    layers.
+    """
+    agent = run_agent('a0')
+    # IPC
+    ipc_addr = str(uuid4())
+    address = agent.bind('PUSH', addr=ipc_addr, transport='ipc')
+    assert address.transport == 'ipc'
+    assert address.address.name == ipc_addr
+    # TCP
+    while True:
+        try:
+            # Bind to random port
+            port = random.randrange(10000, 20000)
+            tcp_addr = '127.0.0.1:%s' % port
+            tcp_addr = SocketAddress('127.0.0.1', port)
+            address = agent.bind('PUSH', addr=tcp_addr, transport='tcp')
+            break
+        except Exception:
+            pass
+    assert address.transport == 'tcp'
+    assert address.address == tcp_addr
+
+
+def test_agent_ipc_from_different_folders(nsproxy):
+    """
+    IPC should work well even when agents are run from different folders.
+    """
+    class Wdagent(Agent):
+        def on_init(self):
+            self.received = []
+
+    def receive(agent, message):
+        agent.received.append(message)
+
+    dira = mkdtemp()
+    dirb = mkdtemp()
+    assert dira != dirb
+
+    # First agent run for directory `a`
+    os.chdir(dira)
+    a = run_agent('a', base=Wdagent)
+    random_addr = a.bind('PULL', transport='ipc', handler=receive)
+    set_addr = a.bind('PULL', addr='qwer', transport='ipc', handler=receive)
+
+    # Second agent run for directory `b`
+    os.chdir(dirb)
+    b = run_agent('b', base=Wdagent)
+    b.connect(random_addr, alias='random')
+    b.connect(set_addr, alias='set')
+    b.send('random', 'foo')
+    b.send('set', 'bar')
+
+    # Wait for `a` to receive the message
+    random_received = wait_agent_attr(a, data='foo', timeout=1)
+    set_received = wait_agent_attr(a, data='bar', timeout=1)
+
+    # Clean directories
+    rmtree(dira)
+    rmtree(dirb)
+
+    assert random_received
+    assert set_received
diff --git a/osbrain/tests/test_proxy.py b/osbrain/tests/test_proxy.py
index 56b25ac..50b94b4 100644
--- a/osbrain/tests/test_proxy.py
+++ b/osbrain/tests/test_proxy.py
@@ -1,11 +1,11 @@
 """
 Proxy module tests.
 """
-import os
 import time
 
 import pytest
 
+import osbrain
 from osbrain import run_agent
 from osbrain import Agent
 from osbrain import Proxy
@@ -169,13 +169,13 @@ def test_agent_proxy_safe_and_unsafe_property(nsproxy):
     """
     run_agent('foo', base=DelayAgent)
     # Safe environment
-    os.environ['OSBRAIN_DEFAULT_SAFE'] = 'true'
+    osbrain.config['SAFE'] = True
     proxy = Proxy('foo')
     assert proxy._safe
     assert proxy.safe._safe
     assert not proxy.unsafe._safe
     # Unsafe environment
-    os.environ['OSBRAIN_DEFAULT_SAFE'] = 'false'
+    osbrain.config['SAFE'] = False
     proxy = Proxy('foo')
     assert not proxy._safe
     assert proxy.safe._safe
@@ -200,13 +200,13 @@ def test_agent_proxy_safe_and_unsafe_parameter(nsproxy):
     """
     run_agent('foo', base=DelayAgent)
     # Safe environment
-    os.environ['OSBRAIN_DEFAULT_SAFE'] = 'true'
+    osbrain.config['SAFE'] = True
     proxy = Proxy('foo')
     assert proxy._safe
     proxy = Proxy('foo', safe=False)
     assert not proxy._safe
     # Unsafe environment
-    os.environ['OSBRAIN_DEFAULT_SAFE'] = 'false'
+    osbrain.config['SAFE'] = False
     proxy = Proxy('foo')
     assert not proxy._safe
     proxy = Proxy('foo', safe=True)
@@ -219,7 +219,7 @@ def test_agent_proxy_safe_and_unsafe_calls_property_safe(nsproxy):
     When using the `safe` property, calls are expected to wait until the main
     thread is able to process them to avoid concurrency.
     """
-    os.environ['OSBRAIN_DEFAULT_SAFE'] = 'false'
+    osbrain.config['SAFE'] = False
     worker = setup_bussy_worker(nsproxy)
     assert not worker._safe
     t0 = time.time()
@@ -236,7 +236,7 @@ def test_agent_proxy_safe_and_unsafe_calls_property_unsafe(nsproxy):
     When using the `unsafe` property, calls are not expected to wait until
     the main thread is able to process them (concurrency is allowed).
     """
-    os.environ['OSBRAIN_DEFAULT_SAFE'] = 'true'
+    osbrain.config['SAFE'] = True
     worker = setup_bussy_worker(nsproxy)
     assert worker._safe
     t0 = time.time()
@@ -255,7 +255,7 @@ def test_agent_proxy_safe_and_unsafe_calls_environ_safe(nsproxy):
     When using the `safe` property, calls are expected to wait until the main
     thread is able to process them to avoid concurrency.
     """
-    os.environ['OSBRAIN_DEFAULT_SAFE'] = 'true'
+    osbrain.config['SAFE'] = True
     worker = setup_bussy_worker(nsproxy)
     t0 = time.time()
     assert worker.listen() == 'OK'
@@ -269,7 +269,7 @@ def test_agent_proxy_safe_and_unsafe_calls_environ_unsafe(nsproxy):
     When using the `unsafe` property, calls are not expected to wait until
     the main thread is able to process them (concurrency is allowed).
     """
-    os.environ['OSBRAIN_DEFAULT_SAFE'] = 'false'
+    osbrain.config['SAFE'] = False
     worker = setup_bussy_worker(nsproxy)
     t0 = time.time()
     assert worker.listen() == 'OK'