1import traceback
2
3from autotest_lib.tko import status_lib, utils as tko_utils
4
5
6class parser(object):
7    """
8    Abstract parser base class. Provides a generic implementation of the
9    standard parser interfaction functions. The derived classes must
10    implement a state_iterator method for this class to be useful.
11    """
12    def start(self, job):
13        """ Initialize the parser for processing the results of
14        'job'."""
15        # initialize all the basic parser parameters
16        self.job = job
17        self.finished = False
18        self.line_buffer = status_lib.line_buffer()
19        # create and prime the parser state machine
20        self.state = self.state_iterator(self.line_buffer)
21        self.state.next()
22
23
24    def process_lines(self, lines):
25        """ Feed 'lines' into the parser state machine, and return
26        a list of all the new test results produced."""
27        self.line_buffer.put_multiple(lines)
28        try:
29            return self.state.next()
30        except StopIteration:
31            msg = ("WARNING: parser was called to process status "
32                   "lines after it was end()ed\n"
33                   "Current traceback:\n" +
34                   traceback.format_exc() +
35                   "\nCurrent stack:\n" +
36                   "".join(traceback.format_stack()))
37            tko_utils.dprint(msg)
38            return []
39
40
41    def end(self, lines=[]):
42        """ Feed 'lines' into the parser state machine, signal to the
43        state machine that no more lines are forthcoming, and then
44        return a list of all the new test results produced."""
45        self.line_buffer.put_multiple(lines)
46        # run the state machine to clear out the buffer
47        self.finished = True
48        try:
49            return self.state.next()
50        except StopIteration:
51            msg = ("WARNING: parser was end()ed multiple times\n"
52                   "Current traceback:\n" +
53                   traceback.format_exc() +
54                   "\nCurrent stack:\n" +
55                   "".join(traceback.format_stack()))
56            tko_utils.dprint(msg)
57            return []
58
59
60    @staticmethod
61    def make_job(dir):
62        """ Create a new instance of the job model used by the
63        parser, given a results directory."""
64        raise NotImplementedError
65
66
67    def state_iterator(self, buffer):
68        """ A generator method that implements the actual parser
69        state machine. """
70        raise NotImplementedError
71