Changeset 951ab1b for server


Ignore:
Timestamp:
Jan 11, 2012, 10:32:20 PM (12 years ago)
Author:
Jessica B. Hamrick <jhamrick@…>
Branches:
no-cups
Children:
190bfb4
Parents:
d518298
git-author:
Jessica B. Hamrick <jhamrick@…> (01/11/12 22:32:15)
git-committer:
Jessica B. Hamrick <jhamrick@…> (01/11/12 22:32:20)
Message:

Add support for verifying documents in job.py

Location:
server
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • server/lib/gutenbach/server/errors.py

    reee389a r951ab1b  
    3535               (self.errstr[self.state], hex(self.state))
    3636
     37class InvalidDocument(Exception):
     38    pass
    3739class MissingDataException(Exception):
    3840    pass
  • server/lib/gutenbach/server/job.py

    ra2b0582 r951ab1b  
    1 from .errors import InvalidJobStateException, MissingDataException
     1from . import errors
    22from .player import Player
    33from gutenbach.ipp import JobStates as States
     
    2323        self.name = name
    2424        self.priority = priority
    25         self._why_done = None
    2625
    2726        if document is not None:
    2827            self.spool(document)
     28
     29        self._why_done = None
    2930
    3031    def __repr__(self):
     
    5253        try:
    5354            self._id = max(int(val), -1)
    54         except TypeError:
     55        except:
    5556            self._id = -1
    5657
     
    6263        try:
    6364            self._priority = max(int(val), 1)
    64         except TypeError:
     65        except:
    6566            self._priority = 1
    6667
     
    103104        return size
    104105
     106    ######################################################################
     107    ###                            State                               ###
     108    ######################################################################
     109
    105110    @property
    106111    def is_valid(self):
     
    145150    @property
    146151    def is_done(self):
     152        """Whether the job is done playing, regardless of whether it
     153        completed successfully or not.
     154
     155        """
    147156        return (self.is_valid and \
    148157                self.player is not None and \
     
    150159                (self._why_done == "cancelled" or \
    151160                 self._why_done == "aborted")
     161
     162    @property
     163    def is_completed(self):
     164        """Whether the job completed successfully.
     165
     166        """
     167        return self.is_done and self._why_done == "completed"
     168
     169    @property
     170    def is_cancelled(self):
     171        """Whether the job was cancelled.
     172
     173        """
     174        return self.is_done and self._why_done == "cancelled"
     175
     176    @property
     177    def is_aborted(self):
     178        """Whether the job was aborted.
     179
     180        """
     181        return self.is_done and self._why_done == "aborted"
    152182
    153183    @property
     
    167197        elif self.is_playing and self.is_paused:
    168198            state = States.STOPPED
    169         elif self.is_done and self._why_done == "completed":
     199        elif self.is_completed:
    170200            state = States.COMPLETE
    171         elif self.is_done and self._why_done == "cancelled":
     201        elif self.is_cancelled:
    172202            state = States.CANCELLED
    173         elif self.is_done and self._why_done == "aborted":
     203        elif self.is_aborted:
    174204            state = States.ABORTED
    175205        else:
     
    181211    ######################################################################
    182212
    183     def spool(self, document):
    184         if not self.is_valid:
    185             raise InvalidJobStateException(self.state)
     213    @staticmethod
     214    def verify_document(document):
     215        if not hasattr(document, "name"):
     216            raise errors.InvalidDocument, "no name attribute"
     217        if not hasattr(document, "read"):
     218            raise errors.InvalidDocument, "no read attribute"
     219        if not hasattr(document, "close"):
     220            raise errors.InvalidDocument, "no close attribute"
     221
     222    def spool(self, document=None):
     223        """Non-blocking spool.  Job must be valid, and the document
     224        must be an open file handler.
     225
     226        Raises
     227        ------
     228        InvalidDocument
     229            If the document is not valid.
     230        InvalidJobStateException
     231            If the job is not valid or it is already
     232            spooled/ready/finished.
     233
     234        """
     235
     236        if not self.is_valid or self.state != States.HELD:
     237            raise errors.InvalidJobStateException(self.state)
     238        self.verify_document(document)
    186239        self.document = document.name
    187240        self.player = Player(document)
     
    189242
    190243    def play(self):
    191         """Non-blocking play function.  Sets the job state to
    192         PROCESSING.
     244        """Non-blocking play.  Job must be ready.
    193245
    194246        Raises
     
    202254        # valid
    203255        if not self.is_ready:
    204             raise InvalidJobStateException(self.state)
     256            raise errors.InvalidJobStateException(self.state)
    205257       
    206258        # and set the state to processing if we're good to go
     
    214266
    215267    def pause(self):
    216         """Non-blocking pause function.  Sets the job state to
    217         STOPPED.
     268        """Non-blocking pause.  Job must be playing.
     269
     270        Raises
     271        ------
     272        InvalidJobStateException
     273            If the job is not playing.
    218274
    219275        """
    220276       
    221277        if not self.is_playing:
    222             raise InvalidJobStateException(self.state)
     278            raise errors.InvalidJobStateException(self.state)
    223279        self.player.mplayer_pause()
    224280
    225281    def cancel(self):
     282        """Non-blocking cancel. The job must not have previously
     283        finished (i.e., cannot be aborted, cancelled, or completed).
     284        This should be used to stop the job following an external
     285        request.
     286
     287        Raises
     288        ------
     289        InvalidJobStateException
     290            If the job has already finished.
     291
     292        """
     293       
    226294        def _cancelled():
    227295            logger.info("cancelled job %s" % str(self))
     
    232300            self.player.mplayer_stop()
    233301        elif self.is_done and not self._why_done == "cancelled":
    234             raise InvalidJobStateException(self.state)
     302            raise errors.InvalidJobStateException(self.state)
    235303        else:
    236304            _cancelled()
    237305
    238306    def abort(self):
     307        """Non-blocking abort. The job must not have previously
     308        finished (i.e., cannot be aborted, cancelled, or completed).
     309        This should be used to stop the job following internal errors.
     310
     311        Raises
     312        ------
     313        InvalidJobStateException
     314            If the job has already finished.
     315
     316        """
     317
    239318        def _aborted():
    240319            logger.info("aborted job %s" % str(self))
     
    245324            self.player.mplayer_stop()
    246325        elif self.is_done and not self._why_done == "aborted":
    247             raise InvalidJobStateException(self.state)
     326            raise errors.InvalidJobStateException(self.state)
    248327        else:
    249328            _aborted()
  • server/test/server/job.py

    r345c476 r951ab1b  
    44import unittest
    55import tempfile
     6import sys
    67
    78def make_tempfile():
     
    3738        self.assertFalse(self.job.is_paused)
    3839        self.assertFalse(self.job.is_done)
     40        self.assertFalse(self.job.is_completed)
     41        self.assertFalse(self.job.is_cancelled)
     42        self.assertFalse(self.job.is_aborted)
    3943
    4044    def testSpool(self):
    41         fh = make_tempfile()
    42         # This should fail, because the id hasn't been set
    43         self.assertFalse(self.job.is_valid)
    44         self.job.id = 1
    45         self.assertTrue(self.job.is_valid)
    46         self.assertFalse(self.job.is_ready)
    47         self.job.spool(fh)
    48         self.assertEqual(self.job.document, fh.name)
    49         self.assertNotEqual(self.job.player, None)
    50         self.assertEqual(self.job.creator, "")
    51         self.assertEqual(self.job.state, States.PENDING)
    52         self.assertTrue(self.job.is_ready)
    53         self.job.abort()
     45        fh = tempfile.NamedTemporaryFile()
     46        self.assertRaises(errors.InvalidJobStateException, self.job.spool, fh)
     47        fh.close()
    5448    def testPlay(self):
    5549        self.assertRaises(errors.InvalidJobStateException, self.job.play)
     
    5852    def testCancel(self):
    5953        self.job.cancel()
     54        self.assertTrue(self.job.is_cancelled)
    6055        self.assertEqual(self.job.state, States.CANCELLED)
    6156    def testAbort(self):
    6257        self.job.abort()
     58        self.assertTrue(self.job.is_aborted)
    6359        self.assertEqual(self.job.state, States.ABORTED)
    6460
     
    6662
    6763    def testBadJobId(self):
    68         self.job = GutenbachJob(job_id=-2)
    69         self.assertEqual(self.job.id, -1)
    70         self.job.id = -2
    71         self.assertEqual(self.job.id, -1)
     64        job = GutenbachJob(job_id=-2)
     65        self.assertEqual(job.id, -1)
     66        job.id = -2
     67        self.assertEqual(job.id, -1)
    7268
    7369    def testBadCreator(self):
    74         self.job = GutenbachJob(job_id=1, creator=12345)
    75         self.assertEqual(self.job.creator, "12345")
    76         self.job.creator = None
    77         self.assertEqual(self.job.creator, "")
    78         self.job.creator = []
    79         self.assertEqual(self.job.creator, "[]")
     70        job = GutenbachJob(
     71            job_id=1,
     72            creator=12345)
     73        self.assertEqual(job.creator, "12345")
     74        job.creator = None
     75        self.assertEqual(job.creator, "")
     76        job.creator = []
     77        self.assertEqual(job.creator, "[]")
    8078
    8179    def testBadName(self):
    82         self.job = GutenbachJob(job_id=1, creator="foo", name=12345)
    83         self.assertEqual(self.job.name, "12345")
    84         self.job.name = None
    85         self.assertEqual(self.job.name, "")
    86         self.job.name = []
    87         self.assertEqual(self.job.name, "[]")
     80        job = GutenbachJob(
     81            job_id=1,
     82            creator="foo",
     83            name=12345)
     84        self.assertEqual(job.name, "12345")
     85        job.name = None
     86        self.assertEqual(job.name, "")
     87        job.name = []
     88        self.assertEqual(job.name, "[]")
     89
     90    def testBadPriority(self):
     91        job = GutenbachJob(
     92            job_id=1,
     93            creator="foo",
     94            name="test",
     95            priority=-1)
     96        self.assertEqual(job.priority, 1)
     97        job.priority = 0
     98        self.assertEqual(job.priority, 1)
     99        job.priority = 1
     100        self.assertEqual(job.priority, 1)
     101        job.priority = sys.maxint
     102        self.assertEqual(job.priority, sys.maxint)
     103        job.priority = "hello"
     104        self.assertEqual(job.priority, 1)
     105        job.priority = []
     106        self.assertEqual(job.priority, 1)
     107
     108    def testBadDocument(self):
     109        job = GutenbachJob(
     110            job_id=1,
     111            creator="foo",
     112            name="test",
     113            priority=1)
     114        self.assertRaises(errors.InvalidDocument, job.spool, "hello")
     115       
     116class TestGoodGutenbachJob(unittest.TestCase):
     117
     118    def setUp(self):
     119        self.job = GutenbachJob(job_id=1, creator="foo", name="test")
     120
     121    def testSpool(self):
     122        fh = make_tempfile()
     123        self.assertTrue(self.job.is_valid)
     124        self.assertFalse(self.job.is_ready)
     125        self.job.spool(fh)
     126        self.assertTrue(self.job.is_ready)
     127       
     128        # Verify various properties
     129        self.assertEqual(self.job.document, fh.name)
     130        self.assertNotEqual(self.job.player, None)
     131        self.assertEqual(self.job.state, States.PENDING)
     132
     133        self.job.abort()
     134
    88135
    89136if __name__ == "__main__":
Note: See TracChangeset for help on using the changeset viewer.