#!/usr/bin/python
#
# arch-tag: unit tests for NPC interface
# Time-stamp: <2005-09-19 09:58:45 mike>
#

import unittest
import random
import time
try:
    import npc
except:
    from pmacs import npc

class NPCTests(unittest.TestCase):
    boards = range(4)
    channels = range(32)

    def setUp(self):
        self.node = npc.NPC(HOSTNAME)

    def tearDown(self):
        if self.node.is_running():
            self.node.stop_poll()
        self.node = None

    def testADMax(self):
        """Test setting/getting A/D limits"""
        if not 'getADmax' in self.node.methods:
            print 'getADmax not present, test skipped'
            return
        val = 16384
        for i in range(10):
            board = random.choice(self.boards)
            chan = random.choice(self.channels)
            save = self.node.getADmax(board, chan)
            self.node.setADmax(board, chan, val)
            try:
                self.assertEqual(val, self.node.getADmax(board, chan),
                                 'max value not set for (%d, %d)' % (board, chan))
            finally:
                self.node.setADmax(board, chan, save)
            
    def testADError(self):
        """Check that A/D errors are properly reported """
        for i in range(10):
            board = random.choice(self.boards)
            chan = random.choice(self.channels)
            mask = 1L << chan
            self.node.setADerror(board, chan)
            errs = self.node.getADerrors()
            self.assertEqual(errs[board] & mask, mask,
                             'error not set for (%d, %d)' % (board, chan))
            self.node.clearADerror(board, chan)
            errs = self.node.getADerrors()
            self.assertEqual(errs[board] & mask, 0,
                             'error not cleared for (%d, %d)' % (board, chan))

    def testSampling(self):
        """Check sampling interval (~20 second runtime)"""
        self.node.start_poll(interval=1)
        time.sleep(2)
        t0 = self.node.sample_time()[0]
        tstart = t0
        for i in range(10):
            time.sleep(2)
            t = self.node.sample_time()[0]
            dt = t - t0
            self.failUnless(1 < dt <= 3,
                            'bad delta T, %d seconds' % dt)
            t0 = t

    def testSamplingListener(self):
        """Check that polling thread calls 'listeners' (~10 second run time)"""
        self.samples = 0
        self.node.register(self)
        self.node.start_poll(interval=1)
        time.sleep(10)
        self.failUnless(8 < self.samples <= 11,
                        'bad sample count, %d' % self.samples)
        
    def recvSample(self, rec, up):
        if up:
            self.samples += 1

if __name__ == '__main__':
    import sys
    try:
        HOSTNAME = sys.argv[1]
    except IndexError:
        HOSTNAME = 'bitsy.apl.washington.edu'
    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(NPCTests))
    unittest.TextTestRunner(verbosity=2).run(suite)
