1d1086b9a7eb3200a8abad534e4c208086626ab30jadmanskiimport traceback
2d1086b9a7eb3200a8abad534e4c208086626ab30jadmanski
3d1086b9a7eb3200a8abad534e4c208086626ab30jadmanskifrom autotest_lib.tko import status_lib, utils as tko_utils
46e8bf75b13c28c5424fb447ceb4d8749c7a13251jadmanski
56e8bf75b13c28c5424fb447ceb4d8749c7a13251jadmanski
66e8bf75b13c28c5424fb447ceb4d8749c7a13251jadmanskiclass parser(object):
70afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
80afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    Abstract parser base class. Provides a generic implementation of the
90afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    standard parser interfaction functions. The derived classes must
100afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    implement a state_iterator method for this class to be useful.
110afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    """
120afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    def start(self, job):
130afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        """ Initialize the parser for processing the results of
140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        'job'."""
150afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        # initialize all the basic parser parameters
160afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        self.job = job
170afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        self.finished = False
180afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        self.line_buffer = status_lib.line_buffer()
190afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        # create and prime the parser state machine
200afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        self.state = self.state_iterator(self.line_buffer)
210afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        self.state.next()
226e8bf75b13c28c5424fb447ceb4d8749c7a13251jadmanski
236e8bf75b13c28c5424fb447ceb4d8749c7a13251jadmanski
240afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    def process_lines(self, lines):
250afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        """ Feed 'lines' into the parser state machine, and return
260afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        a list of all the new test results produced."""
270afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        self.line_buffer.put_multiple(lines)
280afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        try:
290afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            return self.state.next()
300afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        except StopIteration:
310afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            msg = ("WARNING: parser was called to process status "
320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   "lines after it was end()ed\n"
330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   "Current traceback:\n" +
340afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   traceback.format_exc() +
350afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   "\nCurrent stack:\n" +
360afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   "".join(traceback.format_stack()))
370afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            tko_utils.dprint(msg)
380afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            return []
396e8bf75b13c28c5424fb447ceb4d8749c7a13251jadmanski
406e8bf75b13c28c5424fb447ceb4d8749c7a13251jadmanski
410afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    def end(self, lines=[]):
420afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        """ Feed 'lines' into the parser state machine, signal to the
430afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        state machine that no more lines are forthcoming, and then
440afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        return a list of all the new test results produced."""
450afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        self.line_buffer.put_multiple(lines)
460afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        # run the state machine to clear out the buffer
470afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        self.finished = True
480afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        try:
490afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            return self.state.next()
500afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        except StopIteration:
510afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            msg = ("WARNING: parser was end()ed multiple times\n"
520afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   "Current traceback:\n" +
530afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   traceback.format_exc() +
540afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   "\nCurrent stack:\n" +
550afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski                   "".join(traceback.format_stack()))
560afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            tko_utils.dprint(msg)
570afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski            return []
586e8bf75b13c28c5424fb447ceb4d8749c7a13251jadmanski
596e8bf75b13c28c5424fb447ceb4d8749c7a13251jadmanski
600afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    @staticmethod
610afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    def make_job(dir):
620afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        """ Create a new instance of the job model used by the
630afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        parser, given a results directory."""
648adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        raise NotImplementedError
656e8bf75b13c28c5424fb447ceb4d8749c7a13251jadmanski
666e8bf75b13c28c5424fb447ceb4d8749c7a13251jadmanski
670afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski    def state_iterator(self, buffer):
680afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        """ A generator method that implements the actual parser
690afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski        state machine. """
708adf78936c915df6fd1edb6c592f40a7ed8350a5Dale Curtis        raise NotImplementedError
71