Browse Source

[1427] Getting cached tokens

Michal 'vorner' Vaner 13 years ago
parent
commit
137abb7385

+ 24 - 3
src/lib/python/isc/bind10/socket_cache.py

@@ -18,6 +18,7 @@ Here's the cache for sockets from socket creator.
 """
 """
 
 
 import os
 import os
+import random
 
 
 class SocketError(Exception):
 class SocketError(Exception):
     """
     """
@@ -131,8 +132,8 @@ class Cache:
         # This is a dict from applications to set of tokens used by the
         # This is a dict from applications to set of tokens used by the
         # application, for the sockets already picked up by an application
         # application, for the sockets already picked up by an application
         self._active_apps = {}
         self._active_apps = {}
-        # The sockets live here to be indexed by address and subsequently
-        # by port
+        # The sockets live here to be indexed by protocol, address and
+        # subsequently by port
         self._sockets = {}
         self._sockets = {}
         # These are just the tokens actually in use, so we don't generate
         # These are just the tokens actually in use, so we don't generate
         # dupes. If one is dropped, it can be potentially reclaimed.
         # dupes. If one is dropped, it can be potentially reclaimed.
@@ -173,7 +174,27 @@ class Cache:
         Note that it isn't guaranteed the tokens would be unique and they
         Note that it isn't guaranteed the tokens would be unique and they
         should be used as an opaque handle only.
         should be used as an opaque handle only.
         """
         """
-        pass
+        addr_str = str(address)
+        try:
+            socket = self._sockets[protocol][addr_str][port]
+        except KeyError:
+            # Something in the dicts is not there, so socket is to be
+            # created
+            # TODO
+            pass
+        # Now we get the token, check it is compatible
+        if not socket.shareCompatible(share_mode, share_name):
+            raise ShareError("Cached socket not compatible with mode " +
+                             share_mode + " and name " + share_name)
+        # Grab yet unused token
+        token = 't' + str(random.randint(0, 2^32-1))
+        while token in self._live_tokens:
+            token = 't' + str(random.randint(0, 2^32-1))
+        self._waiting_tokens[token] = socket
+        self._live_tokens.add(token)
+        socket.shares[token] = (share_mode, share_name)
+        socket.waiting_tokens.add(token)
+        return token
 
 
     def get_socket(self, token, application):
     def get_socket(self, token, application):
         """
         """

+ 35 - 0
src/lib/python/isc/bind10/tests/socket_cache_test.py

@@ -134,9 +134,14 @@ class SocketCacheTest(Test):
     def setUp(self):
     def setUp(self):
         """
         """
         Creates the cache for tests with us being the socket creator.
         Creates the cache for tests with us being the socket creator.
+
+        Also creates some more variables for testing.
         """
         """
         Test.setUp(self)
         Test.setUp(self)
         self.__cache = isc.bind10.socket_cache.Cache(self)
         self.__cache = isc.bind10.socket_cache.Cache(self)
+        self.__address = IPAddr("192.0.2.1")
+        self.__socket = isc.bind10.socket_cache.Socket('Test', self.__address,
+                                                       1024, 42)
 
 
     def test_init(self):
     def test_init(self):
         """
         """
@@ -149,6 +154,36 @@ class SocketCacheTest(Test):
         self.assertEqual({}, self.__cache._sockets)
         self.assertEqual({}, self.__cache._sockets)
         self.assertEqual(set(), self.__cache._live_tokens)
         self.assertEqual(set(), self.__cache._live_tokens)
 
 
+    def test_get_token_cached(self):
+        """
+        Check the behaviour of get_token when the requested socket is already
+        cached inside.
+        """
+        self.__cache._sockets = {
+            'UDP': {'192.0.2.1': {42: self.__socket}}
+        }
+        token = self.__cache.get_token('UDP', self.__address, 42, 'ANY',
+                                       'test')
+        # It returned something
+        self.assertIsNotNone(token)
+        # The token is both in the waiting sockets and the live tokens
+        self.assertEqual({token: self.__socket}, self.__cache._waiting_tokens)
+        self.assertEqual(set([token]), self.__cache._live_tokens)
+        # The token got the new share to block any relevant queries
+        self.assertEqual({token: ('ANY', 'test')}, self.__socket.shares)
+        # The socket knows the token is waiting in it
+        self.assertEqual(set([token]), self.__socket.waiting_tokens)
+
+        # If we request one more, with incompatible share, it is rejected
+        self.assertRaises(isc.bind10.socket_cache.ShareError,
+                          self.__cache.get_token, 'UDP', self.__address, 42,
+                          'NO', 'test')
+        # The internals are not changed, so the same checks
+        self.assertEqual({token: self.__socket}, self.__cache._waiting_tokens)
+        self.assertEqual(set([token]), self.__cache._live_tokens)
+        self.assertEqual({token: ('ANY', 'test')}, self.__socket.shares)
+        self.assertEqual(set([token]), self.__socket.waiting_tokens)
+
 if __name__ == '__main__':
 if __name__ == '__main__':
     isc.log.init("bind10")
     isc.log.init("bind10")
     isc.log.resetUnitTestRootLogger()
     isc.log.resetUnitTestRootLogger()