def test_secondEnvironment(self): """ Only a single L{Environment} can extract inherited file descriptors. """ fakeEnvironment = self.initializeEnvironment(3, os.getpid()) first = ListenFDs.fromEnvironment(environ=fakeEnvironment) second = ListenFDs.fromEnvironment(environ=fakeEnvironment) self.assertEqual(list(range(3, 6)), first.inheritedDescriptors()) self.assertEqual([], second.inheritedDescriptors())
def _parseStreamServerTest(self, addressFamily, addressFamilyString): """ Helper for unit tests for L{endpoints._SystemdParser.parseStreamServer} for different address families. Handling of the address family given will be verify. If there is a problem a test-failing exception will be raised. @param addressFamily: An address family constant, like L{socket.AF_INET}. @param addressFamilyString: A string which should be recognized by the parser as representing C{addressFamily}. """ reactor = object() descriptors = [5, 6, 7, 8, 9] index = 3 parser = self._parserClass() parser._sddaemon = ListenFDs(descriptors) server = parser.parseStreamServer(reactor, domain=addressFamilyString, index=str(index)) self.assertIdentical(server.reactor, reactor) self.assertEqual(server.addressFamily, addressFamily) self.assertEqual(server.fileno, descriptors[index])
def getDaemon(self, start, count): """ Invent C{count} new I{file descriptors} (actually integers, attached to no real file description), starting at C{start}. Construct and return a new L{ListenFDs} which will claim those integers represent inherited file descriptors. """ return ListenFDs(range(start, start + count))
def test_nonIntegerFDSVariable(self): """ If the I{LISTEN_FDS} environment variable is set to a string that cannot be parsed as an integer, no inherited descriptors are reported. """ fakeEnvironment = self.initializeEnvironment("hello, world", os.getpid()) sddaemon = ListenFDs.fromEnvironment(environ=fakeEnvironment) self.assertEqual([], sddaemon.inheritedDescriptors())
def test_mismatchedPID(self): """ If the current process PID does not match the PID in the environment, no inherited descriptors are reported. """ fakeEnvironment = self.initializeEnvironment(3, os.getpid() + 1) sddaemon = ListenFDs.fromEnvironment(environ=fakeEnvironment) self.assertEqual([], sddaemon.inheritedDescriptors())
def getDaemon(self, start, count): """ Create a new L{ListenFDs} instance, initialized with a fake environment dictionary which will be set up as systemd would have set it up if C{count} descriptors were being inherited. The descriptors will also start at C{start}. """ fakeEnvironment = self.initializeEnvironment(count, os.getpid()) return ListenFDs.fromEnvironment(environ=fakeEnvironment, start=start)
def test_defaultEnviron(self): """ If the process environment is not explicitly passed to L{Environment.__init__}, the real process environment dictionary is used. """ self.patch(os, "environ", {"LISTEN_PID": str(os.getpid()), "LISTEN_FDS": "5"}) sddaemon = ListenFDs.fromEnvironment() self.assertEqual(list(range(3, 3 + 5)), sddaemon.inheritedDescriptors())
def test_missingFDSVariable(self): """ If the I{LISTEN_FDS} environment variable is not present, no inherited descriptors are reported. """ fakeEnvironment = self.initializeEnvironment(3, os.getpid()) del fakeEnvironment["LISTEN_FDS"] sddaemon = ListenFDs.fromEnvironment(environ=fakeEnvironment) self.assertEqual([], sddaemon.inheritedDescriptors())
def test_missingFDSVariable(self): """ If the I{LISTEN_FDS} environment variable is not present, no inherited descriptors are reported. """ fakeEnvironment = self.initializeEnvironment(3, os.getpid()) del fakeEnvironment['LISTEN_FDS'] sddaemon = ListenFDs.fromEnvironment(environ=fakeEnvironment) self.assertEqual([], sddaemon.inheritedDescriptors())
def test_defaultEnviron(self): """ If the process environment is not explicitly passed to L{Environment.__init__}, the real process environment dictionary is used. """ self.patch(os, 'environ', { 'LISTEN_PID': str(os.getpid()), 'LISTEN_FDS': '5'}) sddaemon = ListenFDs.fromEnvironment() self.assertEqual(range(3, 3 + 5), sddaemon.inheritedDescriptors())
class _SystemdParser(object): """ Stream server endpoint string parser for the I{systemd} endpoint type. @ivar prefix: See L{IStreamClientEndpointStringParser.prefix}. @ivar _sddaemon: A L{ListenFDs} instance used to translate an index into an actual file descriptor. """ implements(IPlugin, IStreamServerEndpointStringParser) _sddaemon = ListenFDs.fromEnvironment() prefix = "systemd" def _parseServer(self, reactor, domain, index): """ Internal parser function for L{_parseServer} to convert the string arguments for a systemd server endpoint into structured arguments for L{AdoptedStreamServerEndpoint}. @param reactor: An L{IReactorSocket} provider. @param domain: The domain (or address family) of the socket inherited from systemd. This is a string like C{"INET"} or C{"UNIX"}, ie the name of an address family from the L{socket} module, without the C{"AF_"} prefix. @type domain: C{str} @param index: An offset into the list of file descriptors inherited from systemd. @type index: C{str} @return: A two-tuple of parsed positional arguments and parsed keyword arguments (a tuple and a dictionary). These can be used to construct an L{AdoptedStreamServerEndpoint}. """ index = int(index) fileno = self._sddaemon.inheritedDescriptors()[index] addressFamily = getattr(socket, 'AF_' + domain) return AdoptedStreamServerEndpoint(reactor, fileno, addressFamily) def parseStreamServer(self, reactor, *args, **kwargs): # Delegate to another function with a sane signature. This function has # an insane signature to trick zope.interface into believing the # interface is correctly implemented. return self._parseServer(reactor, *args, **kwargs)