blob: c934c5869cebfaae8029793350e4841f0a8cb380 [file] [log] [blame]
#!/usr/bin/python
"""Tests for the logos program."""
import random
import select
import signal
import socket
import subprocess
import time
from wvtest.wvtest import *
def macAddressShapedString():
chars = '0123456789abcdef::::::'
return ''.join(random.choice(chars) for x in range(17))
@wvtest
def testLogos():
# We use a SOCK_DGRAM here rather than a normal pipe, because datagram
# sockets are guaranteed never to merge consecutive writes into a single
# packet. That way we can validate the correct merging of write() calls
# into exactly one per line.
sock1, sock2 = socket.socketpair(socket.AF_UNIX, socket.SOCK_DGRAM)
pipefd1, pipefd2 = os.pipe()
pipe1 = os.fdopen(pipefd1, 'r') # for auto-close semantics
pipe2 = os.fdopen(pipefd2, 'w') # for auto-close semantics
os.environ['LOGOS_DEBUG'] = '1'
argv = ['./host-logos', 'fac', '50000']
p = subprocess.Popen(argv, stdin=subprocess.PIPE, stdout=sock1.fileno())
sock1.close()
pipe2.close()
fd1 = p.stdin.fileno()
fd2 = sock2.fileno()
def _Read():
r, w, x = select.select([fd2, pipe1], [], [], 30)
if pipe1 in r:
WVFAIL('subprocess died unexpectedly')
raise Exception('subprocess died unexpectedly with code %d' % p.wait())
elif not r:
raise Exception('read timed out')
return os.read(fd2, 4096)
# basics
os.write(fd1, 'a\nErROR: b\nw: c')
WVPASSEQ('<7>fac: a\n', _Read())
WVPASSEQ('<3>fac: ErROR: b\n', _Read())
r, w, x = select.select([fd2], [], [], 0)
WVFAIL(r)
os.write(fd1, '\n\n')
WVPASSEQ('<4>fac: w: c\n', _Read())
WVPASSEQ('<7>fac: \n', _Read())
# tabs and CR
os.write(fd1, 'a\tb\r\nabba\tbbb\naa\t\tb\tc\n')
WVPASSEQ('<7>fac: a b\n', _Read())
WVPASSEQ('<7>fac: abba bbb\n', _Read())
WVPASSEQ('<7>fac: aa b c\n', _Read())
os.write(fd1, ''.join(chr(i) for i in range(33)) + '\n')
WVPASSEQ(r'<7>fac: ' +
r'\x00\x01\x02\x03\x04\x05\x06\x07\x08 '
+ '\n', _Read())
WVPASSEQ(r'<7>fac: ' +
r'\x0b\x0c\x0e\x0f' +
r'\x10\x11\x12\x13\x14\x15\x16\x17' +
r'\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ' +
'\n', _Read())
# very long lines should be broken, but not missing any characters
sent = ('x ' * 2000)
for c in sent:
os.write(fd1, c)
os.write(fd1, '\nbooga!')
total = ''
while total != sent:
print 'len(total)=%d len(sent)=%d' % (len(total), len(sent))
result = _Read()
WVPASSLT(len(result), len(sent))
WVPASS(result.startswith('<7>fac: '))
WVPASS(result.endswith('\n'))
total += result[8:-1]
if not WVPASS(sent.startswith(total)):
return
result = _Read()
print '%r' % result
WVPASS(result.startswith('<4>fac: W: '))
r, w, x = select.select([fd2], [], [], 0)
WVFAIL(r)
os.write(fd1, '\n')
WVPASSEQ('<7>fac: booga!\n', _Read())
# MAC addresses
os.write(fd1, 'f8:8f:ca:00:00:01\n')
WVPASSEQ('<7>fac: f8:8f:ca:00:XX:XX\n', _Read())
os.write(fd1, '8:8f:ca:00:00:01\n')
WVPASSEQ('<7>fac: 8:8f:ca:00:00:01\n', _Read())
os.write(fd1, '8:8f:ca:00:00:01:\n')
WVPASSEQ('<7>fac: 8:8f:ca:00:00:01:\n', _Read())
os.write(fd1, ':::semicolons:f8:8f:ca:00:00:01:and:after\n')
WVPASSEQ('<7>fac: :::semicolons:f8:8f:ca:00:XX:XX:and:after\n', _Read())
os.write(fd1, 'f8-8f-ca-00-00-01\n')
WVPASSEQ('<7>fac: f8-8f-ca-00-XX-XX\n', _Read())
# Send in random strings to look for crashes.
for x in range(10):
mac = macAddressShapedString()
print 'Trying %s to check for crashes' % mac
os.write(fd1, mac + '\n')
print _Read()
# Filenames
os.write(fd1, 'Accessing /var/media/pictures/MyPicture.jpg for decode\n')
WVPASSEQ('<7>fac: Accessing /var/media/pictures/XXXXXXXXXXXXX for decode\n',
_Read())
os.write(fd1, '/var/media/pictures/MyPicture.jpg\n')
WVPASSEQ('<7>fac: /var/media/pictures/XXXXXXXXXXXXX\n',
_Read())
os.write(fd1, 'Accessing /var/media/videos/MyMovie.mpg for decode\n')
WVPASSEQ('<7>fac: Accessing /var/media/videos/XXXXXXXXXXX for decode\n',
_Read())
os.write(fd1, 'Accessing /var/media/tv/MyTvShow.ts for decode\n')
WVPASSEQ('<7>fac: Accessing /var/media/tv/MyTvShow.ts for decode\n',
_Read())
os.write(fd1, 'check "/var/media/videos/MyTvShow.ts"len=1024\n')
WVPASSEQ('<7>fac: check "/var/media/videos/XXXXXXXXXXX"len=1024\n',
_Read())
# rate limiting
os.write(fd1, (('x'*80) + '\n') * 500)
result = ''
while 'burst limit' not in result:
result = _Read()
print repr(result)
print 'got: %r' % result
WVPASS('rate limiting started')
while 1:
# drain the input until it's idle
r, w, x = select.select([fd1], [], [], 0.1)
if not r:
break
p.send_signal(signal.SIGHUP) # refill the bucket, ending rate limiting
os.write(fd1, 'Awake!\n')
result = ''
while 'burst limit' not in result:
result = _Read()
print 'got: %r' % result
WVPASS('rate limiting finished')
result = ''
while 'Awake!' not in result:
result = _Read()
WVPASS('awake!')
p.stdin.close()
WVPASSEQ(p.wait(), 0)
if __name__ == '__main__':
wvtest_main()