Welcome to mirror list, hosted at ThFree Co, Russian Federation.

dev.gajim.org/gajim/gajim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomk <tomk@no-mail.com>2008-09-01 03:40:06 +0400
committertomk <tomk@no-mail.com>2008-09-01 03:40:06 +0400
commita7c36048b93ec338e23687e29a96d2ac1d420217 (patch)
tree11db0a83c973a3b22aee2cc9f4cc65fbf8a6e38c
parented7dd84cfe8ae8cf624a7894e0a9e9de40ebe6f8 (diff)
- renamed src/common/nslookup.py to resolver.py
- refactored resolver code and added asynchronous resolver based on patch by Damien Thebault[1] * Uses libasyncns-python[2]. If it's not available, old nslookup resolver is used) * works for SRV requests only at the moment [1] https://www.lagaule.org/pipermail/gajim-devel/2008-July/000460.html [2] https://code.launchpad.net/libasyncns-python
-rw-r--r--src/common/resolver.py (renamed from src/common/nslookup.py)173
-rw-r--r--src/common/xmpp/client_nb.py1
-rwxr-xr-xsrc/gajim.py9
-rw-r--r--test/lib/__init__.py50
-rwxr-xr-xtest/lib/data.py77
-rw-r--r--test/lib/mock.py (renamed from test/mock.py)2
-rw-r--r--test/lib/mocks.py145
-rw-r--r--test/lib/notify.py (renamed from test/notify.py)2
-rw-r--r--test/mocks.py68
-rw-r--r--test/test_resolver.py95
10 files changed, 517 insertions, 105 deletions
diff --git a/src/common/nslookup.py b/src/common/resolver.py
index ae535993e..52c297ff7 100644
--- a/src/common/nslookup.py
+++ b/src/common/resolver.py
@@ -1,4 +1,4 @@
-## common/nslookup.py
+## common/resolver.py
##
## Copyright (C) 2006 Dimitur Kirov <dkirov@gmail.com>
##
@@ -23,6 +23,7 @@ import re
from xmpp.idlequeue import *
+# needed for nslookup
if os.name == 'nt':
from subprocess import * # python24 only. we ask this for Windows
elif os.name == 'posix':
@@ -34,13 +35,138 @@ ns_type_pattern = re.compile('^[a-z]+$')
# match srv host_name
host_pattern = re.compile('^[a-z0-9\-._]*[a-z0-9]\.[a-z]{2,}$')
-class Resolver:
+USE_LIBASYNCNS = False
+
+try:
+ #raise ImportError("Manually disabled libasync")
+ import libasyncns
+ USE_LIBASYNCNS = True
+ log.info("libasyncns-python loaded")
+except ImportError:
+ log.debug("Import of libasyncns-python failed, getaddrinfo will block", exc_info=True)
+
+ # FIXME: Remove these prints before release, replace with a warning dialog.
+ print >> sys.stderr, "=" * 79
+ print >> sys.stderr, "libasyncns-python not installed which means:"
+ print >> sys.stderr, " - nslookup will be used for SRV and TXT requests"
+ print >> sys.stderr, " - getaddrinfo will block"
+ print >> sys.stderr, "libasyncns-python can be found at https://launchpad.net/libasyncns-python"
+ print >> sys.stderr, "=" * 79
+
+
+def get_resolver(idlequeue):
+ if USE_LIBASYNCNS:
+ return LibAsyncNSResolver()
+ else:
+ return NSLookupResolver(idlequeue)
+
+class CommonResolver():
+ def __init__(self):
+ # dict {"host+type" : list of records}
+ self.resolved_hosts = {}
+ # dict {"host+type" : list of callbacks}
+ self.handlers = {}
+
+ def resolve(self, host, on_ready, type='srv'):
+ assert(type in ['srv', 'txt'])
+ if not host:
+ # empty host, return empty list of srv records
+ on_ready([])
+ return
+ if self.resolved_hosts.has_key(host+type):
+ # host is already resolved, return cached values
+ on_ready(host, self.resolved_hosts[host+type])
+ return
+ if self.handlers.has_key(host+type):
+ # host is about to be resolved by another connection,
+ # attach our callback
+ self.handlers[host+type].append(on_ready)
+ else:
+ # host has never been resolved, start now
+ self.handlers[host+type] = [on_ready]
+ self.start_resolve(host, type)
+
+ def _on_ready(self, host, type, result_list):
+ # practically it is impossible to be the opposite, but who knows :)
+ if not self.resolved_hosts.has_key(host+type):
+ self.resolved_hosts[host+type] = result_list
+ if self.handlers.has_key(host+type):
+ for callback in self.handlers[host+type]:
+ callback(host, result_list)
+ del(self.handlers[host+type])
+
+ def start_resolve(self, host, type):
+ pass
+
+
+class LibAsyncNSResolver(CommonResolver):
+ '''
+ Asynchronous resolver using libasyncns-python. process() method has to be called
+ in order to proceed the pending requests.
+ Based on patch submitted by Damien Thebault.
+ '''
+ def __init__(self):
+ self.asyncns = libasyncns.Asyncns()
+ CommonResolver.__init__(self)
+
+ def start_resolve(self, host, type):
+ type = libasyncns.ns_t_srv
+ if type == 'txt': type = libasyncns.ns_t_txt
+ resq = self.asyncns.res_query(host, libasyncns.ns_c_in, type)
+ resq.userdata = {'host':host, 'type':type}
+
+ # getaddrinfo to be done
+ #def resolve_name(self, dname, callback):
+ #resq = self.asyncns.getaddrinfo(dname)
+ #resq.userdata = {'callback':callback, 'dname':dname}
+
+ def _on_ready(self, host, type, result_list):
+ if type == libasyncns.ns_t_srv: type = 'srv'
+ elif type == libasyncns.ns_t_txt: type = 'txt'
+
+ CommonResolver._on_ready(self, host, type, result_list)
+
+
+ def process(self):
+ try:
+ self.asyncns.wait(False)
+ resq = self.asyncns.get_next()
+ except:
+ return True
+ if type(resq) == libasyncns.ResQuery:
+ # TXT or SRV result
+ while resq is not None:
+ try:
+ rl = resq.get_done()
+ except:
+ rl = []
+ if rl:
+ for r in rl:
+ r['prio'] = r['pref']
+ self._on_ready(
+ host = resq.userdata['host'],
+ type = resq.userdata['type'],
+ result_list = rl)
+ try:
+ resq = self.asyncns.get_next()
+ except:
+ resq = None
+ elif type(resq) == libasyncns.AddrInfoQuery:
+ # getaddrinfo result (A or AAAA)
+ rl = resq.get_done()
+ resq.userdata['callback'](resq.userdata['dname'], rl)
+ return True
+
+class NSLookupResolver(CommonResolver):
+ '''
+ Asynchronous DNS resolver calling nslookup. Processing of pending requests
+ is invoked from idlequeue which is watching file descriptor of pipe of stdout
+ of nslookup process.
+ '''
def __init__(self, idlequeue):
self.idlequeue = idlequeue
- # dict {host : list of srv records}
- self.resolved_hosts = {}
- # dict {host : list of callbacks}
- self.handlers = {}
+ self.process = False
+ CommonResolver.__init__(self)
def parse_srv_result(self, fqdn, result):
''' parse the output of nslookup command and return list of
@@ -133,42 +259,19 @@ class Resolver:
'prio': prio})
return hosts
- def _on_ready(self, host, result):
+ def _on_ready(self, host, type, result):
# nslookup finished, parse the result and call the handlers
result_list = self.parse_srv_result(host, result)
+ CommonResolver._on_ready(self, host, type, result_list)
- # practically it is impossible to be the opposite, but who knows :)
- if not self.resolved_hosts.has_key(host):
- self.resolved_hosts[host] = result_list
- if self.handlers.has_key(host):
- for callback in self.handlers[host]:
- callback(host, result_list)
- del(self.handlers[host])
- def start_resolve(self, host):
+ def start_resolve(self, host, type):
''' spawn new nslookup process and start waiting for results '''
- ns = NsLookup(self._on_ready, host)
+ ns = NsLookup(self._on_ready, host, type)
ns.set_idlequeue(self.idlequeue)
ns.commandtimeout = 10
ns.start()
- def resolve(self, host, on_ready):
- if not host:
- # empty host, return empty list of srv records
- on_ready([])
- return
- if self.resolved_hosts.has_key(host):
- # host is already resolved, return cached values
- on_ready(host, self.resolved_hosts[host])
- return
- if self.handlers.has_key(host):
- # host is about to be resolved by another connection,
- # attach our callback
- self.handlers[host].append(on_ready)
- else:
- # host has never been resolved, start now
- self.handlers[host] = [on_ready]
- self.start_resolve(host)
# TODO: move IdleCommand class in other file, maybe helpers ?
class IdleCommand(IdleObject):
@@ -268,7 +371,7 @@ class IdleCommand(IdleObject):
self._return_result()
class NsLookup(IdleCommand):
- def __init__(self, on_result, host='_xmpp-client', type = 'srv'):
+ def __init__(self, on_result, host='_xmpp-client', type='srv'):
IdleCommand.__init__(self, on_result)
self.commandtimeout = 10
self.host = host.lower()
@@ -288,7 +391,7 @@ class NsLookup(IdleCommand):
def _return_result(self):
if self.result_handler:
- self.result_handler(self.host, self.result)
+ self.result_handler(self.host, self.type, self.result)
self.result_handler = None
# below lines is on how to use API and assist in testing
diff --git a/src/common/xmpp/client_nb.py b/src/common/xmpp/client_nb.py
index b7603cc08..088475b90 100644
--- a/src/common/xmpp/client_nb.py
+++ b/src/common/xmpp/client_nb.py
@@ -40,6 +40,7 @@ class NonBlockingClient:
:param domain: domain - for to: attribute (from account info)
:param idlequeue: processing idlequeue
:param caller: calling object - it has to implement method _event_dispatcher
+ which is called from dispatcher instance
'''
self.Namespace = protocol.NS_CLIENT
self.defaultNamespace = self.Namespace
diff --git a/src/gajim.py b/src/gajim.py
index be9eaab1a..e5f0b3e03 100755
--- a/src/gajim.py
+++ b/src/gajim.py
@@ -260,7 +260,7 @@ import common.sleepy
from common.xmpp import idlequeue
from common.zeroconf import connection_zeroconf
-from common import nslookup
+from common import resolver
from common import proxy65_manager
from common import socks5
from common import helpers
@@ -3077,7 +3077,7 @@ class Interface:
# gajim.idlequeue.process() each foo miliseconds
gajim.idlequeue = GlibIdleQueue()
# resolve and keep current record of resolved hosts
- gajim.resolver = nslookup.Resolver(gajim.idlequeue)
+ gajim.resolver = resolver.get_resolver(gajim.idlequeue)
gajim.socks5queue = socks5.SocksQueue(gajim.idlequeue,
self.handle_event_file_rcv_completed,
self.handle_event_file_progress)
@@ -3222,6 +3222,11 @@ class Interface:
self.last_ftwindow_update = 0
gobject.timeout_add(100, self.autoconnect)
+
+ # when using libasyncns we need to process resolver in regular intervals
+ if resolver.USE_LIBASYNCNS:
+ gobject.timeout_add(200, gajim.resolver.process)
+
if os.name == 'nt':
gobject.timeout_add(200, self.process_connections)
else:
diff --git a/test/lib/__init__.py b/test/lib/__init__.py
new file mode 100644
index 000000000..2b99a7e23
--- /dev/null
+++ b/test/lib/__init__.py
@@ -0,0 +1,50 @@
+import sys
+import os.path
+import getopt
+
+use_x = True
+shortargs = 'hnv:'
+longargs = 'help no-x verbose='
+opts, args = getopt.getopt(sys.argv[1:], shortargs, longargs.split())
+for o, a in opts:
+ if o in ('-n', '--no-x'):
+ use_x = False
+
+gajim_root = os.path.join(os.path.abspath(os.path.dirname(__file__)), '../..')
+
+# look for modules in the CWD, then gajim/test/lib, then gajim/src, then everywhere else
+sys.path.insert(1, gajim_root + '/src')
+sys.path.insert(1, gajim_root + '/test/lib')
+
+# a temporary version of ~/.gajim for testing
+configdir = gajim_root + '/test/tmp'
+
+# define _ for i18n
+import __builtin__
+__builtin__._ = lambda x: x
+
+import os
+
+def setup_env():
+ # wipe config directory
+ if os.path.isdir(configdir):
+ import shutil
+ shutil.rmtree(configdir)
+
+ os.mkdir(configdir)
+
+ import common.configpaths
+ common.configpaths.gajimpaths.init(configdir)
+ common.configpaths.gajimpaths.init_profile()
+
+ # for some reason common.gajim needs to be imported before xmpppy?
+ from common import gajim
+
+ gajim.DATA_DIR = gajim_root + '/data'
+ gajim.use_x = use_x
+
+ if use_x:
+ import gtkgui_helpers
+ gtkgui_helpers.GLADE_DIR = gajim_root + '/data/glade'
+
+# vim: se ts=3:
diff --git a/test/lib/data.py b/test/lib/data.py
new file mode 100755
index 000000000..074a7def8
--- /dev/null
+++ b/test/lib/data.py
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+account1 = u'acc1'
+account2 = u'Cool"chârßéµö'
+account3 = u'dingdong.org'
+
+contacts = {}
+contacts[account1] = {
+ u'myjid@'+account1: {
+ 'ask': None, 'groups': [], 'name': None, 'resources': {},
+ 'subscription': u'both'},
+ u'default1@gajim.org': {
+ 'ask': None, 'groups': [], 'name': None, 'resources': {},
+ 'subscription': u'both'},
+ u'default2@gajim.org': {
+ 'ask': None, 'groups': [u'GroupA',], 'name': None, 'resources': {},
+ 'subscription': u'both'},
+ u'Cool"chârßéµö@gajim.org': {
+ 'ask': None, 'groups': [u'<Cool"chârßéµö', u'GroupB'],
+ 'name': None, 'resources': {}, 'subscription': u'both'},
+ u'samejid@gajim.org': {
+ 'ask': None, 'groups': [u'GroupA',], 'name': None, 'resources': {},
+ 'subscription': u'both'}
+}
+contacts[account2] = {
+ u'myjid@'+account2: {
+ 'ask': None, 'groups': [], 'name': None, 'resources': {},
+ 'subscription': u'both'},
+ u'default3@gajim.org': {
+ 'ask': None, 'groups': [u'GroupC',], 'name': None, 'resources': {},
+ 'subscription': u'both'},
+ u'asksubfrom@gajim.org': {
+ 'ask': u'subscribe', 'groups': [u'GroupA',], 'name': None,
+ 'resources': {}, 'subscription': u'from'},
+ u'subto@gajim.org': {
+ 'ask': None, 'groups': [u'GroupB'], 'name': None, 'resources': {},
+ 'subscription': u'to'},
+ u'samejid@gajim.org': {
+ 'ask': None, 'groups': [u'GroupA', u'GroupB'], 'name': None,
+ 'resources': {}, 'subscription': u'both'}
+}
+contacts[account3] = {
+ #u'guypsych0\\40h.com@msn.dingdong.org': {
+ # 'ask': None, 'groups': [], 'name': None, 'resources': {},
+ # 'subscription': u'both'},
+ u'guypsych0%h.com@msn.delx.cjb.net': {
+ 'ask': u'subscribe', 'groups': [], 'name': None,
+ 'resources': {}, 'subscription': u'from'},
+ #u'guypsych0%h.com@msn.jabber.wiretrip.org': {
+ # 'ask': None, 'groups': [], 'name': None, 'resources': {},
+ # 'subscription': u'to'},
+ #u'guypsycho\\40g.com@gtalk.dingdong.org': {
+ # 'ask': None, 'groups': [], 'name': None,
+ # 'resources': {}, 'subscription': u'both'}
+}
+# We have contacts that are not in roster but only specified in the metadata
+metacontact_data = [
+ [{'account': account3,
+ 'jid': u'guypsych0\\40h.com@msn.dingdong.org',
+ 'order': 0},
+ {'account': account3,
+ 'jid': u'guypsych0%h.com@msn.delx.cjb.net',
+ 'order': 0},
+ {'account': account3,
+ 'jid': u'guypsych0%h.com@msn.jabber.wiretrip.org',
+ 'order': 0},
+ {'account': account3,
+ 'jid': u'guypsycho\\40g.com@gtalk.dingdong.org',
+ 'order': 0}],
+
+ [{'account': account1,
+ 'jid': u'samejid@gajim.org',
+ 'order': 0},
+ {'account': account2,
+ 'jid': u'samejid@gajim.org',
+ 'order': 0}]
+ ]
+
diff --git a/test/mock.py b/test/lib/mock.py
index 7c20056c1..02b94b511 100644
--- a/test/mock.py
+++ b/test/lib/mock.py
@@ -463,3 +463,5 @@ CALLABLE = callable
+
+# vim: se ts=3: \ No newline at end of file
diff --git a/test/lib/mocks.py b/test/lib/mocks.py
new file mode 100644
index 000000000..8d0e80f96
--- /dev/null
+++ b/test/lib/mocks.py
@@ -0,0 +1,145 @@
+# gajim-specific mock objects
+from mock import Mock
+
+from common import gajim
+
+from common.connection_handlers import ConnectionHandlersBase
+
+class MockConnection(Mock, ConnectionHandlersBase):
+ def __init__(self, account, *args):
+ Mock.__init__(self, *args)
+ ConnectionHandlersBase.__init__(self)
+
+ self.name = account
+ self.connected = 2
+ self.mood = {}
+ self.activity = {}
+ self.tune = {}
+ self.blocked_contacts = {}
+ self.blocked_groups = {}
+ self.sessions = {}
+
+ gajim.interface.instances[account] = {'infos': {}, 'disco': {},
+ 'gc_config': {}, 'search': {}}
+ gajim.interface.minimized_controls[account] = {}
+ gajim.contacts.add_account(account)
+ gajim.groups[account] = {}
+ gajim.gc_connected[account] = {}
+ gajim.automatic_rooms[account] = {}
+ gajim.newly_added[account] = []
+ gajim.to_be_removed[account] = []
+ gajim.nicks[account] = gajim.config.get_per('accounts', account, 'name')
+ gajim.block_signed_in_notifications[account] = True
+ gajim.sleeper_state[account] = 0
+ gajim.encrypted_chats[account] = []
+ gajim.last_message_time[account] = {}
+ gajim.status_before_autoaway[account] = ''
+ gajim.transport_avatar[account] = {}
+ gajim.gajim_optional_features[account] = []
+ gajim.caps_hash[account] = ''
+
+ gajim.connections[account] = self
+
+class MockWindow(Mock):
+ def __init__(self, *args):
+ Mock.__init__(self, *args)
+ self.window = Mock()
+ self._controls = {}
+
+ def get_control(self, jid, account):
+ try:
+ return self._controls[account][jid]
+ except KeyError:
+ return None
+
+ def has_control(self, jid, acct):
+ return self.get_control(jid, acct) is not None
+
+ def new_tab(self, ctrl):
+ account = ctrl.account
+ jid = ctrl.jid
+
+ if account not in self._controls:
+ self._controls[account] = {}
+
+ if jid not in self._controls[account]:
+ self._controls[account][jid] = {}
+
+ self._controls[account][jid] = ctrl
+
+ def __nonzero__(self):
+ return True
+
+class MockChatControl(Mock):
+ def __init__(self, jid, account, *args):
+ Mock.__init__(self, *args)
+
+ self.jid = jid
+ self.account = account
+
+ self.parent_win = MockWindow({'get_active_control': self})
+ self.session = None
+
+ def set_session(self, sess):
+ self.session = sess
+
+ def __nonzero__(self):
+ return True
+
+ def __eq__(self, other):
+ return self is other
+
+class MockInterface(Mock):
+ def __init__(self, *args):
+ Mock.__init__(self, *args)
+ gajim.interface = self
+ self.msg_win_mgr = Mock()
+ self.roster = Mock()
+
+ self.remote_ctrl = None
+ self.instances = {}
+ self.minimized_controls = {}
+ self.status_sent_to_users = Mock()
+
+ if gajim.use_x:
+ self.jabber_state_images = {'16': {}, '32': {}, 'opened': {},
+ 'closed': {}}
+
+ import gtkgui_helpers
+ gtkgui_helpers.make_jabber_state_images()
+ else:
+ self.jabber_state_images = {'16': Mock(), '32': Mock(),
+ 'opened': Mock(), 'closed': Mock()}
+
+class MockLogger(Mock):
+ def __init__(self):
+ Mock.__init__(self, {'write': None, 'get_transports_type': {}})
+
+class MockContact(Mock):
+ def __nonzero__(self):
+ return True
+
+import random
+
+class MockSession(Mock):
+ def __init__(self, conn, jid, thread_id, type):
+ Mock.__init__(self)
+
+ self.conn = conn
+ self.jid = jid
+ self.type = type
+ self.thread_id = thread_id
+
+ if not self.thread_id:
+ self.thread_id = '%0x' % random.randint(0, 10000)
+
+ def __repr__(self):
+ return '<MockSession %s>' % self.thread_id
+
+ def __nonzero__(self):
+ return True
+
+ def __eq__(self, other):
+ return self is other
+
+# vim: se ts=3:
diff --git a/test/notify.py b/test/lib/notify.py
index 2e55e6959..f14100af3 100644
--- a/test/notify.py
+++ b/test/lib/notify.py
@@ -13,3 +13,5 @@ def get_show_in_roster(event, account, contact, session = None):
def get_show_in_systray(event, account, contact, type_ = None):
return True
+
+# vim: se ts=3: \ No newline at end of file
diff --git a/test/mocks.py b/test/mocks.py
deleted file mode 100644
index 213f79ddf..000000000
--- a/test/mocks.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# gajim-specific mock objects
-from mock import Mock
-
-from common import gajim
-
-class MockConnection(Mock):
- def __init__(self, name, *args):
- Mock.__init__(self, *args)
- self.name = name
- gajim.connections[name] = self
-
-class MockWindow(Mock):
- def __init__(self, *args):
- Mock.__init__(self, *args)
- self.window = Mock()
-
-class MockChatControl(Mock):
- def __init__(self, *args):
- Mock.__init__(self, *args)
-
- self.parent_win = MockWindow({'get_active_control': self})
- self.session = None
-
- def set_session(self, sess):
- self.session = sess
-
- def __nonzero__(self):
- return True
-
- def __eq__(self, other):
- return self is other
-
-class MockInterface(Mock):
- def __init__(self, acct, *args):
- Mock.__init__(self, *args)
- self.msg_win_mgr = Mock()
- self.roster = Mock()
-
- self.remote_ctrl = None
- self.minimized_controls = { acct: {} }
-
-class MockLogger(Mock):
- def __init__(self):
- Mock.__init__(self, {'write': None})
-
-class MockContact(Mock):
- def __nonzero__(self):
- return True
-
-import random
-
-class MockSession(Mock):
- def __init__(self, conn, jid, thread_id, type):
- Mock.__init__(self)
-
- self.conn = conn
- self.jid = jid
- self.type = type
- self.thread_id = thread_id
-
- if not self.thread_id:
- self.thread_id = '%0x' % random.randint(0, 10000)
-
- def __repr__(self):
- print '<MockSession %s>' % self.thread_id
-
- def __nonzero__(self):
- return True
diff --git a/test/test_resolver.py b/test/test_resolver.py
new file mode 100644
index 000000000..4cab122a0
--- /dev/null
+++ b/test/test_resolver.py
@@ -0,0 +1,95 @@
+import unittest
+
+import time
+
+import lib
+lib.setup_env()
+
+from common import resolver
+from gajim import GlibIdleQueue
+
+from mock import Mock, expectParams
+from mocks import *
+
+import gtk
+
+
+GMAIL_SRV_NAME = '_xmpp-client._tcp.gmail.com'
+NONSENSE_NAME = 'sfsdfsdfsdf.sdfs.fsd'
+JABBERCZ_TXT_NAME = '_xmppconnect.jabber.cz'
+JABBERCZ_SRV_NAME = '_xmpp-client._tcp.jabber.cz'
+
+TEST_LIST = [(GMAIL_SRV_NAME, 'srv', True),
+ (NONSENSE_NAME, 'srv', False),
+ (JABBERCZ_SRV_NAME, 'srv', True)]
+
+class TestResolver(unittest.TestCase):
+ def setUp(self):
+ self.iq = GlibIdleQueue()
+ self.reset()
+ self.resolver = None
+
+ def reset(self):
+ self.flag = False
+ self.expect_results = False
+ self.nslookup = False
+ self.resolver = None
+
+ def testLibAsyncNSResolver(self):
+ self.reset()
+ if not resolver.USE_LIBASYNCNS:
+ print 'testLibAsyncResolver: libasyncns-python not installed'
+ return
+ self.resolver = resolver.LibAsyncNSResolver()
+
+ for name, type, expect_results in TEST_LIST:
+ self.expect_results = expect_results
+ self.runLANSR(name, type)
+ self.flag = False
+
+ def runLANSR(self, name, type):
+ self.resolver.resolve(
+ host = name,
+ type = type,
+ on_ready = self.myonready)
+ while not self.flag:
+ time.sleep(1)
+ self.resolver.process()
+
+
+ def myonready(self, name, result_set):
+ print 'on_ready called ...'
+ print 'hostname: %s' % name
+ print 'result set: %s' % result_set
+ print 'res.resolved_hosts: %s' % self.resolver.resolved_hosts
+ if self.expect_results:
+ self.assert_(len(result_set) > 0)
+ else:
+ self.assert_(result_set == [])
+ self.flag = True
+ if self.nslookup: self._testNSLR()
+
+
+ def testNSLookupResolver(self):
+ self.reset()
+ self.nslookup = True
+ self.resolver = resolver.NSLookupResolver(self.iq)
+ self.test_list = TEST_LIST
+ self._testNSLR()
+ try:
+ gtk.main()
+ except KeyboardInterrupt:
+ print 'KeyboardInterrupt caught'
+
+ def _testNSLR(self):
+ if self.test_list == []:
+ gtk.main_quit()
+ return
+ name, type, self.expect_results = self.test_list.pop()
+ self.resolver.resolve(
+ host = name,
+ type = type,
+ on_ready = self.myonready)
+
+if __name__ == '__main__':
+ unittest.main()