Tests: lttngtest: raise NotImplementedError in abstract class methods
[lttng-tools.git] / tests / utils / lttngtest / lttngctl.py
CommitLineData
ef945e4d
JG
1#!/usr/bin/env python3
2#
3# Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4#
5# SPDX-License-Identifier: GPL-2.0-only
6
7import abc
8import random
9import string
10import pathlib
11import enum
12from typing import Optional, Type, Union, List
13
14"""
15Defines an abstract interface to control LTTng tracing.
16
17The various control concepts are defined by this module. You can use them with a
18Controller to interact with a session daemon.
19
20This interface is not comprehensive; it currently provides a subset of the
21control functionality that is used by tests.
22"""
23
24
ce8470c9
MJ
25def _generate_random_string(length):
26 # type: (int) -> str
ef945e4d
JG
27 return "".join(
28 random.choice(string.ascii_lowercase + string.digits) for _ in range(length)
29 )
30
31
32class ContextType(abc.ABC):
33 """Base class representing a tracing context field."""
34
35 pass
36
37
38class VpidContextType(ContextType):
39 """Application's virtual process id."""
40
41 pass
42
43
44class VuidContextType(ContextType):
45 """Application's virtual user id."""
46
47 pass
48
49
50class VgidContextType(ContextType):
51 """Application's virtual group id."""
52
53 pass
54
55
56class JavaApplicationContextType(ContextType):
57 """A java application-specific context field is a piece of state which the application provides."""
58
ce8470c9
MJ
59 def __init__(
60 self,
61 retriever_name, # type: str
62 field_name, # type: str
63 ):
64 self._retriever_name = retriever_name # type: str
65 self._field_name = field_name # type: str
ef945e4d
JG
66
67 @property
ce8470c9
MJ
68 def retriever_name(self):
69 # type: () -> str
ef945e4d
JG
70 return self._retriever_name
71
72 @property
ce8470c9
MJ
73 def field_name(self):
74 # type: () -> str
ef945e4d
JG
75 return self._field_name
76
77
544d8425 78@enum.unique
ef945e4d
JG
79class TracingDomain(enum.Enum):
80 """Tracing domain."""
81
544d8425
MJ
82 User = "User space tracing domain"
83 Kernel = "Linux kernel tracing domain."
84 Log4j = "Log4j tracing back-end."
85 JUL = "Java Util Logging tracing back-end."
86 Python = "Python logging module tracing back-end."
87
88 def __repr__(self):
89 return "<%s.%s>" % (self.__class__.__name__, self.name)
ef945e4d
JG
90
91
a631186c
JG
92@enum.unique
93class BufferSharingPolicy(enum.Enum):
94 """Buffer sharing policy."""
95
96 PerUID = "Per-UID buffering"
97 PerPID = "Per-PID buffering"
98
99 def __repr__(self):
100 return "<%s.%s>" % (self.__class__.__name__, self.name)
101
102
ef945e4d
JG
103class EventRule(abc.ABC):
104 """Event rule base class, see LTTNG-EVENT-RULE(7)."""
105
106 pass
107
108
109class LogLevelRule:
110 pass
111
112
113class LogLevelRuleAsSevereAs(LogLevelRule):
ce8470c9
MJ
114 def __init__(self, level):
115 # type: (int)
ef945e4d
JG
116 self._level = level
117
118 @property
ce8470c9
MJ
119 def level(self):
120 # type: () -> int
ef945e4d
JG
121 return self._level
122
123
124class LogLevelRuleExactly(LogLevelRule):
ce8470c9
MJ
125 def __init__(self, level):
126 # type: (int)
ef945e4d
JG
127 self._level = level
128
129 @property
ce8470c9
MJ
130 def level(self):
131 # type: () -> int
ef945e4d
JG
132 return self._level
133
134
135class TracepointEventRule(EventRule):
136 def __init__(
137 self,
ce8470c9
MJ
138 name_pattern=None, # type: Optional[str]
139 filter_expression=None, # type: Optional[str]
140 log_level_rule=None, # type: Optional[LogLevelRule]
141 name_pattern_exclusions=None, # type: Optional[List[str]]
ef945e4d 142 ):
ce8470c9
MJ
143 self._name_pattern = name_pattern # type: Optional[str]
144 self._filter_expression = filter_expression # type: Optional[str]
145 self._log_level_rule = log_level_rule # type: Optional[LogLevelRule]
146 self._name_pattern_exclusions = (
147 name_pattern_exclusions
148 ) # type: Optional[List[str]]
ef945e4d
JG
149
150 @property
ce8470c9
MJ
151 def name_pattern(self):
152 # type: () -> Optional[str]
ef945e4d
JG
153 return self._name_pattern
154
155 @property
ce8470c9
MJ
156 def filter_expression(self):
157 # type: () -> Optional[str]
ef945e4d
JG
158 return self._filter_expression
159
160 @property
ce8470c9
MJ
161 def log_level_rule(self):
162 # type: () -> Optional[LogLevelRule]
ef945e4d
JG
163 return self._log_level_rule
164
165 @property
ce8470c9
MJ
166 def name_pattern_exclusions(self):
167 # type: () -> Optional[List[str]]
ef945e4d
JG
168 return self._name_pattern_exclusions
169
170
171class UserTracepointEventRule(TracepointEventRule):
172 def __init__(
173 self,
ce8470c9
MJ
174 name_pattern=None, # type: Optional[str]
175 filter_expression=None, # type: Optional[str]
176 log_level_rule=None, # type: Optional[LogLevelRule]
177 name_pattern_exclusions=None, # type: Optional[List[str]]
ef945e4d
JG
178 ):
179 TracepointEventRule.__init__(**locals())
180
181
182class KernelTracepointEventRule(TracepointEventRule):
183 def __init__(
184 self,
ce8470c9
MJ
185 name_pattern=None, # type: Optional[str]
186 filter_expression=None, # type: Optional[str]
187 log_level_rule=None, # type: Optional[LogLevelRule]
188 name_pattern_exclusions=None, # type: Optional[List[str]]
ef945e4d
JG
189 ):
190 TracepointEventRule.__init__(**locals())
191
192
193class Channel(abc.ABC):
194 """
195 A channel is an object which is responsible for a set of ring buffers. It is
196 associated to a domain and
197 """
198
199 @staticmethod
ce8470c9
MJ
200 def _generate_name():
201 # type: () -> str
ef945e4d
JG
202 return "channel_{random_id}".format(random_id=_generate_random_string(8))
203
204 @abc.abstractmethod
ce8470c9
MJ
205 def add_context(self, context_type):
206 # type: (ContextType) -> None
fe3442d8 207 raise NotImplementedError
ef945e4d
JG
208
209 @property
210 @abc.abstractmethod
ce8470c9
MJ
211 def domain(self):
212 # type: () -> TracingDomain
fe3442d8 213 raise NotImplementedError
ef945e4d
JG
214
215 @property
216 @abc.abstractmethod
ce8470c9
MJ
217 def name(self):
218 # type: () -> str
fe3442d8 219 raise NotImplementedError
ef945e4d
JG
220
221 @abc.abstractmethod
ce8470c9
MJ
222 def add_recording_rule(self, rule) -> None:
223 # type: (Type[EventRule]) -> None
fe3442d8 224 raise NotImplementedError
ef945e4d
JG
225
226
227class SessionOutputLocation(abc.ABC):
228 pass
229
230
231class LocalSessionOutputLocation(SessionOutputLocation):
ce8470c9
MJ
232 def __init__(self, trace_path):
233 # type: (pathlib.Path)
ef945e4d
JG
234 self._path = trace_path
235
236 @property
ce8470c9
MJ
237 def path(self):
238 # type: () -> pathlib.Path
ef945e4d
JG
239 return self._path
240
241
242class ProcessAttributeTracker(abc.ABC):
243 """
244 Process attribute tracker used to filter before the evaluation of event
245 rules.
246
247 Note that this interface is currently limited as it doesn't allow changing
248 the tracking policy. For instance, it is not possible to set the tracking
249 policy back to "all" once it has transitioned to "include set".
250 """
251
544d8425 252 @enum.unique
ef945e4d 253 class TrackingPolicy(enum.Enum):
544d8425 254 INCLUDE_ALL = """
ef945e4d
JG
255 Track all possible process attribute value of a given type (i.e. no filtering).
256 This is the default state of a process attribute tracker.
544d8425
MJ
257 """
258 EXCLUDE_ALL = "Exclude all possible process attribute values of a given type."
259 INCLUDE_SET = "Track a set of specific process attribute values."
260
261 def __repr__(self):
262 return "<%s.%s>" % (self.__class__.__name__, self.name)
ef945e4d 263
ce8470c9
MJ
264 def __init__(self, policy):
265 # type: (TrackingPolicy)
ef945e4d
JG
266 self._policy = policy
267
268 @property
ce8470c9
MJ
269 def tracking_policy(self):
270 # type: () -> TrackingPolicy
ef945e4d
JG
271 return self._policy
272
273
274class ProcessIDProcessAttributeTracker(ProcessAttributeTracker):
275 @abc.abstractmethod
ce8470c9
MJ
276 def track(self, pid):
277 # type: (int) -> None
fe3442d8 278 raise NotImplementedError
ef945e4d
JG
279
280 @abc.abstractmethod
ce8470c9
MJ
281 def untrack(self, pid):
282 # type: (int) -> None
fe3442d8 283 raise NotImplementedError
ef945e4d
JG
284
285
286class VirtualProcessIDProcessAttributeTracker(ProcessAttributeTracker):
287 @abc.abstractmethod
ce8470c9
MJ
288 def track(self, vpid):
289 # type: (int) -> None
fe3442d8 290 raise NotImplementedError
ef945e4d
JG
291
292 @abc.abstractmethod
ce8470c9
MJ
293 def untrack(self, vpid):
294 # type: (int) -> None
fe3442d8 295 raise NotImplementedError
ef945e4d
JG
296
297
298class UserIDProcessAttributeTracker(ProcessAttributeTracker):
299 @abc.abstractmethod
ce8470c9
MJ
300 def track(self, uid):
301 # type: (Union[int, str]) -> None
fe3442d8 302 raise NotImplementedError
ef945e4d
JG
303
304 @abc.abstractmethod
ce8470c9
MJ
305 def untrack(self, uid):
306 # type: (Union[int, str]) -> None
fe3442d8 307 raise NotImplementedError
ef945e4d
JG
308
309
310class VirtualUserIDProcessAttributeTracker(ProcessAttributeTracker):
311 @abc.abstractmethod
ce8470c9
MJ
312 def track(self, vuid):
313 # type: (Union[int, str]) -> None
fe3442d8 314 raise NotImplementedError
ef945e4d
JG
315
316 @abc.abstractmethod
ce8470c9
MJ
317 def untrack(self, vuid):
318 # type: (Union[int, str]) -> None
fe3442d8 319 raise NotImplementedError
ef945e4d
JG
320
321
322class GroupIDProcessAttributeTracker(ProcessAttributeTracker):
323 @abc.abstractmethod
ce8470c9
MJ
324 def track(self, gid):
325 # type: (Union[int, str]) -> None
fe3442d8 326 raise NotImplementedError
ef945e4d
JG
327
328 @abc.abstractmethod
ce8470c9
MJ
329 def untrack(self, gid):
330 # type: (Union[int, str]) -> None
fe3442d8 331 raise NotImplementedError
ef945e4d
JG
332
333
334class VirtualGroupIDProcessAttributeTracker(ProcessAttributeTracker):
335 @abc.abstractmethod
ce8470c9
MJ
336 def track(self, vgid):
337 # type: (Union[int, str]) -> None
fe3442d8 338 raise NotImplementedError
ef945e4d
JG
339
340 @abc.abstractmethod
ce8470c9
MJ
341 def untrack(self, vgid):
342 # type: (Union[int, str]) -> None
fe3442d8 343 raise NotImplementedError
ef945e4d
JG
344
345
346class Session(abc.ABC):
347 @staticmethod
ce8470c9
MJ
348 def _generate_name():
349 # type: () -> str
ef945e4d
JG
350 return "session_{random_id}".format(random_id=_generate_random_string(8))
351
352 @property
353 @abc.abstractmethod
ce8470c9
MJ
354 def name(self):
355 # type: () -> str
fe3442d8 356 raise NotImplementedError
ef945e4d
JG
357
358 @property
359 @abc.abstractmethod
ce8470c9
MJ
360 def output(self):
361 # type: () -> Optional[Type[SessionOutputLocation]]
fe3442d8 362 raise NotImplementedError
ef945e4d
JG
363
364 @abc.abstractmethod
a631186c
JG
365 def add_channel(
366 self,
367 domain,
368 channel_name=None,
369 buffer_sharing_policy=BufferSharingPolicy.PerUID,
370 ):
371 # type: (TracingDomain, Optional[str], BufferSharingPolicy) -> Channel
ef945e4d 372 """Add a channel with default attributes to the session."""
fe3442d8 373 raise NotImplementedError
ef945e4d
JG
374
375 @abc.abstractmethod
ce8470c9
MJ
376 def start(self):
377 # type: () -> None
fe3442d8 378 raise NotImplementedError
ef945e4d
JG
379
380 @abc.abstractmethod
ce8470c9
MJ
381 def stop(self):
382 # type: () -> None
fe3442d8 383 raise NotImplementedError
ef945e4d
JG
384
385 @abc.abstractmethod
ce8470c9
MJ
386 def destroy(self):
387 # type: () -> None
fe3442d8 388 raise NotImplementedError
ef945e4d 389
b9780062
JG
390 @abc.abstractmethod
391 def is_active(self):
392 # type: () -> bool
fe3442d8 393 raise NotImplementedError
b9780062 394
a8cac44b
JG
395 @abc.abstractmethod
396 def rotate(self):
397 # type: () -> None
398 raise NotImplementedError
399
ef945e4d 400 @abc.abstractproperty
ce8470c9
MJ
401 def kernel_pid_process_attribute_tracker(self):
402 # type: () -> Type[ProcessIDProcessAttributeTracker]
ef945e4d
JG
403 raise NotImplementedError
404
405 @abc.abstractproperty
ce8470c9
MJ
406 def kernel_vpid_process_attribute_tracker(self):
407 # type: () -> Type[VirtualProcessIDProcessAttributeTracker]
ef945e4d
JG
408 raise NotImplementedError
409
410 @abc.abstractproperty
411 def user_vpid_process_attribute_tracker(
412 self,
413 ) -> Type[VirtualProcessIDProcessAttributeTracker]:
ce8470c9 414 # type: () -> Type[VirtualProcessIDProcessAttributeTracker]
ef945e4d
JG
415 raise NotImplementedError
416
417 @abc.abstractproperty
ce8470c9
MJ
418 def kernel_gid_process_attribute_tracker(self):
419 # type: () -> Type[GroupIDProcessAttributeTracker]
ef945e4d
JG
420 raise NotImplementedError
421
422 @abc.abstractproperty
ce8470c9
MJ
423 def kernel_vgid_process_attribute_tracker(self):
424 # type: () -> Type[VirtualGroupIDProcessAttributeTracker]
ef945e4d
JG
425 raise NotImplementedError
426
427 @abc.abstractproperty
ce8470c9
MJ
428 def user_vgid_process_attribute_tracker(self):
429 # type: () -> Type[VirtualGroupIDProcessAttributeTracker]
ef945e4d
JG
430 raise NotImplementedError
431
432 @abc.abstractproperty
ce8470c9
MJ
433 def kernel_uid_process_attribute_tracker(self):
434 # type: () -> Type[UserIDProcessAttributeTracker]
ef945e4d
JG
435 raise NotImplementedError
436
437 @abc.abstractproperty
ce8470c9
MJ
438 def kernel_vuid_process_attribute_tracker(self):
439 # type: () -> Type[VirtualUserIDProcessAttributeTracker]
ef945e4d
JG
440 raise NotImplementedError
441
442 @abc.abstractproperty
ce8470c9
MJ
443 def user_vuid_process_attribute_tracker(self):
444 # type: () -> Type[VirtualUserIDProcessAttributeTracker]
ef945e4d
JG
445 raise NotImplementedError
446
447
448class ControlException(RuntimeError):
449 """Base type for exceptions thrown by a controller."""
450
ce8470c9
MJ
451 def __init__(self, msg):
452 # type: (str)
ef945e4d
JG
453 super().__init__(msg)
454
455
456class Controller(abc.ABC):
457 """
458 Interface of a top-level control interface. A control interface can be, for
459 example, the LTTng client or a wrapper around liblttng-ctl. It is used to
460 create and manage top-level objects of a session daemon instance.
461 """
462
463 @abc.abstractmethod
ce8470c9
MJ
464 def create_session(self, name=None, output=None):
465 # type: (Optional[str], Optional[SessionOutputLocation]) -> Session
ef945e4d
JG
466 """
467 Create a session with an output. Don't specify an output
468 to create a session without an output.
469 """
fe3442d8 470 raise NotImplementedError
b9780062
JG
471
472 @abc.abstractmethod
473 def start_session_by_name(self, name):
474 # type: (str) -> None
475 """
476 Start a session by name.
477 """
fe3442d8 478 raise NotImplementedError
b9780062
JG
479
480 @abc.abstractmethod
481 def start_session_by_glob_pattern(self, pattern):
482 # type: (str) -> None
483 """
484 Start sessions whose name matches `pattern`, see GLOB(7).
485 """
fe3442d8 486 raise NotImplementedError
b9780062
JG
487
488 @abc.abstractmethod
489 def start_sessions_all(self):
490 """
491 Start all sessions visible to the current user.
492 """
493 # type: () -> None
fe3442d8 494 raise NotImplementedError
b9780062
JG
495
496 @abc.abstractmethod
497 def stop_session_by_name(self, name):
498 # type: (str) -> None
499 """
500 Stop a session by name.
501 """
fe3442d8 502 raise NotImplementedError
b9780062
JG
503
504 @abc.abstractmethod
505 def stop_session_by_glob_pattern(self, pattern):
506 # type: (str) -> None
507 """
508 Stop sessions whose name matches `pattern`, see GLOB(7).
509 """
fe3442d8 510 raise NotImplementedError
b9780062
JG
511
512 @abc.abstractmethod
513 def stop_sessions_all(self):
514 """
515 Stop all sessions visible to the current user.
516 """
517 # type: () -> None
fe3442d8 518 raise NotImplementedError
b9780062
JG
519
520 @abc.abstractmethod
521 def destroy_session_by_name(self, name):
522 # type: (str) -> None
523 """
524 Destroy a session by name.
525 """
fe3442d8 526 raise NotImplementedError
b9780062
JG
527
528 @abc.abstractmethod
529 def destroy_session_by_glob_pattern(self, pattern):
530 # type: (str) -> None
531 """
532 Destroy sessions whose name matches `pattern`, see GLOB(7).
533 """
fe3442d8 534 raise NotImplementedError
b9780062
JG
535
536 @abc.abstractmethod
537 def destroy_sessions_all(self):
538 # type: () -> None
539 """
540 Destroy all sessions visible to the current user.
541 """
fe3442d8 542 raise NotImplementedError
b9780062
JG
543
544 @abc.abstractmethod
545 def list_sessions(self):
546 # type: () -> List[Session]
547 """
548 List all sessions visible to the current user.
549 """
fe3442d8 550 raise NotImplementedError
a8cac44b
JG
551
552 @abc.abstractmethod
553 def rotate_session_by_name(self, name, wait=True):
554 # type: (str, bool) -> None
555 """
556 Rotate a session
557 """
558 raise NotImplementedError
559
560 @abc.abstractmethod
561 def schedule_size_based_rotation(self, name, size_bytes):
562 # type: (str, int) -> None
563 """
564 Schedule automatic size-based rotations.
565 """
566 raise NotImplementedError
567
568 @abc.abstractmethod
569 def schedule_time_based_rotation(self, name, period_seconds):
570 # type: (str, int) -> None
571 """
572 Schedule automatic time-based rotations.
573 """
574 raise NotImplementedError
This page took 0.059103 seconds and 4 git commands to generate.