2013-04-07 2 views
0

Я сделал класс Тун, который оборачивает pytun.TunTapDevice:Туннельный интерфейс модульного тестирования

from pytun import TunTapDevice 

class Tun(object): 
    def __init__(self,name='tun',addr=None,dstaddr=None,netmask=None,mtu=None): 

     tun = TunTapDevice(name=name) 
     if addr  : tun.addr  = addr 
     if dstaddr : tun.dstaddr = dstaddr 
     if netmask : tun.netmask = netmask 
     if mtu  : tun.mtu  = mtu 
     self._tun = tun 
     self.up = self._tun.up 
     self.down = self._tun.down 
     self.read = self._tun.read 
     self.write = self._tun.write 
     self.close = self._tun.close 


    @property 
    def name(self): 
     return self._tun.name 

    @property 
    def mtu(self): 
     return self._tun.mtu 

Вопрос не о том, как написать туннель, а о том, как написать тест-случай, чтобы гарантировать ее работы правильно в unix-подобных oses, используя python unit-testing.

Что я должен выписать ему для обеспечения работы? Может быть, запрос ARP, ICMP, DNS пакет или что-нибудь еще:

class TestTunnel(unittest.TestCase): 

    def setUp(self): 
     self.tun = Tun(name='tun0', addr='192.168.0.23', netmask='255.255.255.0',mtu=1500) 

    def test_tunnel(self): 
     self.tun.write(?????) 
     self.assertEqual(self.tun.read(),????) 

EDIT 1:

наконец я получил его этим кодом:

from select import select 
import dpkt 
import struct 

class TunnelTestCase(unittest.TestCase): 

    def setUp(self): 

     self.tun = Tun(name='testtun', 
         addr='192.168.6.92', 
         dstaddr='192.168.6.93', 
         netmask='255.255.255.0', 
         mtu=1500) 
     self.tun.up() 

    def _ip2str(self,ip): 
     return '.'.join([str(i) for i in struct.unpack('!BBBB',ip)]) 

    def test_echo(self): 
     reqPack = dpkt.ip.IP('E\x00\x00T\x00\[email protected]\[email protected]\x01\xac\x9f\xc0\xa8\x06]\xc0\xa8\x06\\\x08\x00\x1c\xae\t\xc7\x00\x01\x0f\x8adQq\xab\x01\x00\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./') 
     self.tun.write(reqPack.pack()) 

     r,_w,_ex = select([self.tun],[],[],4) 
     if len(r) and r[0] == self.tun: 
      replyPack = dpkt.ip.IP(self.tun.read()) 
      self.assertEqual(self._ip2str(replyPack.src), self.tun.addr) 
      self.assertEqual(self._ip2str(replyPack.dst), self.tun.dstaddr) 
      return 

     self.assert_(False, 'ICMP Echo timeout, the tunnel interface may not works properly in your system.') 

ответ

1

Вы можете просто быть в состоянии заимствовать тестовые примеры из pytun и упростить их. На самом деле, я думаю, что тестирование фактических подключений выполняется в их пакете, поэтому, если вы не пытаетесь проверить что-то значительно другое, вы можете уйти с просто проверять тесты без изменений. https://github.com/montag451/pytun/tree/master/test

Поскольку это сырой сокет, вы можете просто попросить отправить простое сообщение ascii от клиента и проверить его получение сервером, а затем отправить сервер обратно подтверждение, на которое вы можете утверждать.

+0

Заранее спасибо – pylover

+0

Мне нужно проверить туннель автоматически, тест montag необходимо запустить из командной строки и передать некоторые аргументы для работы. поэтому я планирую писать два сокета в режиме клиент-сервер, для связи через интерфейс туннеля. клиент отправляет что-нибудь, а сервер просто отдает все, что получает. какая у тебя идея? – pylover

+1

Я бы просто выполнил настройку сервера внутри метода setUp и передал то, что ранее было бы передано вручную через командную строку. Возможно, вам придется разветвлять его на другом потоке, поскольку он может блокироваться (это также означает, что вам нужен способ убить этот другой поток). Да, просто сделайте простое эхо «Hello World» от клиента и утвердитесь против этого при чтении данных из сокета как для сервера, так и для клиента. Вы можете сделать все настройки в автоматическом режиме, не нужно настраивать сервер вручную, передавая аргументы командной строки только для запуска теста. –