Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(746)

Side by Side Diff: appengine/findit/crash/flag_manager.py

Issue 2593093003: [Predator] Add flag manager and flag manager test. (Closed)
Patch Set: Fix nits. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | appengine/findit/crash/test/flag_manager_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Module handling flags while doing stream parsing.
6
7 ``ParsingFlag`` has a name, a turn_on_condition function which returns a boolean
8 predicate and a boolean value. We say that a flag with the boolean value
9 ``True`` is "on", and a flag with the boolean value ``False`` is "off".
10 The turn_on_condition function is used to check whether a flag should be turned
11 "on" while it is "off".
12
13 ``FlagManager`` is a class for managing all the flags while doing stream
14 parsing. In order to be tracked during stream parsing, all flags must be
15 registered in ``FlagManager`` with a certain group (differentiate different
16 namespaces).
17
18 For example:
19
20
21 stacktrace = "blabla\nSUMMARY:\nblabla"
22 flag = ParsingFlag('after_summary_flag', lambda line: 'SUMMARY:' in line,
23 value=False)
24 flag_manager = FlagManager()
25 flag_manager.Register('stacktrace_group', flag)
26
27 for line in stacktrace.splitlines():
28 flag_manager.ConditionallyTurnOnFlags(line)
29
30
31 The ``after_summary_flag`` will be turned on (set the value to True) when
32 parsing the second line, because the initial value of the flag is ``False`` and
33 the turn_on_condition function returns ``True`` for the second line.
34
35 The flag will stay "on", until ``flag.Off()`` is called to set the value to
36 ``False`` explictly.
37 """
38
39 from collections import defaultdict
40
41
42 class ParsingFlag(object):
43 """Represents a flag in stream parsing.
44
45 This object serves like a delegation to manipulate flag of object,
46 turn_on_condition will be used to evaluate the flag value.
47 """
48 def __init__(self, name, turn_on_condition=None, value=False):
49 """
50 Args:
51 name (str): Name of the flag.
52 turn_on_condition (callable): The function takes a str line as input and
53 returns a boolean value. When the flag is "off", this funtion can be
54 called to check whether the flag should be turned on or not.
55 Note, if the flag is "on", the return value of this function means "do
56 nothing" and shouldn't affect the value of the flag.
57 value (bool): Initial value of the flag.
58 """
59 self._name = name
60 self._turn_on_condition = turn_on_condition
61 self._value = value
62
63 @property
64 def name(self):
65 return self._name
66
67 @property
68 def value(self):
69 return self._value
70
71 def TurnOn(self):
72 self._value = True
73
74 def TurnOff(self):
75 self._value = False
76
77 def __nonzero__(self):
78 return self._value
79
80 __bool__ = __nonzero__
81
82 def ConditionallyTurnOn(self, line):
83 """When the flag is off, turns on it if turn_on_conditions met."""
84 if (not self._value and self._turn_on_condition and
85 self._turn_on_condition(line)):
86 self.TurnOn()
87
88
89 class FlagManager(object):
90 """A manager to track all the registered flags.
91
92 FlagManager collects and manages flags based on group names. FlagManager takes
93 care of manipulating flags during the stream parsing, including evaluating
94 based on the turn_on_conditions of flags, and resetting flags.
95
96 Note, flag manager only keeps distinct flags(with distinct flag name), and one
97 flag cannot be registered with multiple groups.
98 """
99
100 def __init__(self):
101 self.flag_groups = defaultdict(list)
102 self.flags = {}
103
104 def ClearFlags(self):
105 """Deletes all the flags."""
106 self.flag_groups = defaultdict(list)
107 self.flags = {}
108
109 def Register(self, group_name, flag):
110 """Registers a flag with a group.
111
112 Flags under the same group should have the same scope.
113 For example, in stacktrace parsing, the scope of a flag like
114 ``after_sumary_line`` is the whole stacktrace, so it should be under
115 ``stacktrace_flags`` group, while the scope of
116 ``callstack_top_frame_has_no_symbol`` is callstack, and it should be
117 under ``callstack_flags`` group.
118 """
119 self.flag_groups[group_name].append(flag)
120 self.flags[flag.name] = flag
121
122 def GetAllFlags(self):
123 """Returns all registered flags."""
124 return self.flags.values()
125
126 def GetGroupFlags(self, group_name):
127 """Returns a certain group of flags."""
128 return self.flag_groups.get(group_name, [])
129
130 def ResetAllFlags(self):
131 """Turns off all registered flags."""
132 for flag in self.GetAllFlags():
133 flag.TurnOff()
134
135 def ResetGroupFlags(self, group_name):
136 """Turns off a certain group of flags."""
137 for flag in self.GetGroupFlags(group_name):
138 flag.TurnOff()
139
140 def ConditionallyTurnOnFlags(self, line):
141 """Turns on "off" flags when turn_on_conditions are met."""
142 for flag in self.GetAllFlags():
143 flag.ConditionallyTurnOn(line)
144
145 def Get(self, flag_name):
146 """Gets the instance with flag_name."""
147 return self.flags.get(flag_name)
148
149 def TurnOn(self, flag_name):
150 """Sets the instance with flag_name to True."""
151 flag = self.flags.get(flag_name)
152 if flag is None:
153 return
154
155 flag.TurnOn()
156
157 def TurnOff(self, flag_name):
158 """Sets the instance with flag_name to False."""
159 flag = self.flags.get(flag_name)
160 if flag is None:
161 return
162
163 flag.TurnOff()
OLDNEW
« no previous file with comments | « no previous file | appengine/findit/crash/test/flag_manager_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698