~percona-core/percona-server/5.5

« back to all changes in this revision

Viewing changes to python-for-subunit2junitxml/subunit/progress_model.py

  • Committer: Stewart Smith
  • Date: 2011-10-05 06:14:21 UTC
  • mto: This revision was merged to the branch mainline in revision 177.
  • Revision ID: stewart@flamingspork.com-20111005061421-fp6t1wuey0a8iw1a
add subunit2junitxml and needed libraries

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
#  subunit: extensions to Python unittest to get test results from subprocesses.
 
3
#  Copyright (C) 2009  Robert Collins <robertc@robertcollins.net>
 
4
#
 
5
#  Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
 
6
#  license at the users choice. A copy of both licenses are available in the
 
7
#  project source as Apache-2.0 and BSD. You may not use this file except in
 
8
#  compliance with one of these two licences.
 
9
#  
 
10
#  Unless required by applicable law or agreed to in writing, software
 
11
#  distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
 
12
#  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 
13
#  license you chose for the specific language governing permissions and
 
14
#  limitations under that license.
 
15
#
 
16
 
 
17
"""Support for dealing with progress state."""
 
18
 
 
19
class ProgressModel(object):
 
20
    """A model of progress indicators as subunit defines it.
 
21
    
 
22
    Instances of this class represent a single logical operation that is
 
23
    progressing. The operation may have many steps, and some of those steps may
 
24
    supply their own progress information. ProgressModel uses a nested concept
 
25
    where the overall state can be pushed, creating new starting state, and
 
26
    later pushed to return to the prior state. Many user interfaces will want
 
27
    to display an overall summary though, and accordingly the pos() and width()
 
28
    methods return overall summary information rather than information on the
 
29
    current subtask.
 
30
 
 
31
    The default state is 0/0 - indicating that the overall progress is unknown.
 
32
    Anytime the denominator of pos/width is 0, rendering of a ProgressModel
 
33
    should should take this into consideration.
 
34
 
 
35
    :ivar: _tasks. This private attribute stores the subtasks. Each is a tuple:
 
36
        pos, width, overall_numerator, overall_denominator. The overall fields
 
37
        store the calculated overall numerator and denominator for the state
 
38
        that was pushed.
 
39
    """
 
40
 
 
41
    def __init__(self):
 
42
        """Create a ProgressModel.
 
43
        
 
44
        The new model has no progress data at all - it will claim a summary
 
45
        width of zero and position of 0.
 
46
        """
 
47
        self._tasks = []
 
48
        self.push()
 
49
 
 
50
    def adjust_width(self, offset):
 
51
        """Adjust the with of the current subtask."""
 
52
        self._tasks[-1][1] += offset
 
53
 
 
54
    def advance(self):
 
55
        """Advance the current subtask."""
 
56
        self._tasks[-1][0] += 1
 
57
 
 
58
    def pop(self):
 
59
        """Pop a subtask off the ProgressModel.
 
60
 
 
61
        See push for a description of how push and pop work.
 
62
        """
 
63
        self._tasks.pop()
 
64
 
 
65
    def pos(self):
 
66
        """Return how far through the operation has progressed."""
 
67
        if not self._tasks:
 
68
            return 0
 
69
        task = self._tasks[-1]
 
70
        if len(self._tasks) > 1:
 
71
            # scale up the overall pos by the current task or preserve it if
 
72
            # no current width is known.
 
73
            offset = task[2] * (task[1] or 1)
 
74
        else:
 
75
            offset = 0
 
76
        return offset + task[0]
 
77
 
 
78
    def push(self):
 
79
        """Push a new subtask.
 
80
 
 
81
        After pushing a new subtask, the overall progress hasn't changed. Calls
 
82
        to adjust_width, advance, set_width will only after the progress within
 
83
        the range that calling 'advance' would have before - the subtask
 
84
        represents progressing one step in the earlier task.
 
85
 
 
86
        Call pop() to restore the progress model to the state before push was
 
87
        called.
 
88
        """
 
89
        self._tasks.append([0, 0, self.pos(), self.width()])
 
90
 
 
91
    def set_width(self, width):
 
92
        """Set the width of the current subtask."""
 
93
        self._tasks[-1][1] = width
 
94
 
 
95
    def width(self):
 
96
        """Return the total width of the operation."""
 
97
        if not self._tasks:
 
98
            return 0
 
99
        task = self._tasks[-1]
 
100
        if len(self._tasks) > 1:
 
101
            # scale up the overall width by the current task or preserve it if
 
102
            # no current width is known.
 
103
            return task[3] * (task[1] or 1)
 
104
        else:
 
105
            return task[1]
 
106