ronnie
2022-10-14 1504bb53e29d3d46222c0b3ea994fc494b48e153
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
#pylint: disable-msg=C0111
 
"""
Internal global error types
"""
 
import sys, traceback
from traceback import format_exception
 
# Add names you want to be imported by 'from errors import *' to this list.
# This must be list not a tuple as we modify it to include all of our
# the Exception classes we define below at the end of this file.
__all__ = ['format_error']
 
 
def format_error():
    t, o, tb = sys.exc_info()
    trace = format_exception(t, o, tb)
    # Clear the backtrace to prevent a circular reference
    # in the heap -- as per tutorial
    tb = ''
 
    return ''.join(trace)
 
 
class TimeoutException(Exception):
    """Generic exception raised on retry timeouts."""
 
 
class JobContinue(SystemExit):
    """Allow us to bail out requesting continuance."""
 
 
class JobComplete(SystemExit):
    """Allow us to bail out indicating continuation not required."""
 
 
class AutotestError(Exception):
    """The parent of all errors deliberatly thrown within the client code."""
 
 
class JobError(AutotestError):
    """Indicates an error which terminates and fails the whole job (ABORT)."""
 
 
class UnhandledJobError(JobError):
    """Indicates an unhandled error in a job."""
    def __init__(self, unhandled_exception):
        if isinstance(unhandled_exception, JobError):
            JobError.__init__(self, *unhandled_exception.args)
        elif isinstance(unhandled_exception, basestring):
            JobError.__init__(self, unhandled_exception)
        else:
            msg = "Unhandled %s: %s"
            msg %= (unhandled_exception.__class__.__name__,
                    unhandled_exception)
            msg += "\n" + traceback.format_exc()
            JobError.__init__(self, msg)
 
 
class TestBaseException(AutotestError):
    """The parent of all test exceptions."""
    # Children are required to override this.  Never instantiate directly.
    exit_status = "NEVER_RAISE_THIS"
 
 
class TestError(TestBaseException):
    """Indicates that something went wrong with the test harness itself."""
    exit_status = "ERROR"
 
 
class TestNAError(TestBaseException):
    """Indictates that the test is Not Applicable.  Should be thrown
    when various conditions are such that the test is inappropriate."""
    exit_status = "TEST_NA"
 
 
class TestFail(TestBaseException):
    """Indicates that the test failed, but the job will not continue."""
    exit_status = "FAIL"
 
 
class TestWarn(TestBaseException):
    """Indicates that bad things (may) have happened, but not an explicit
    failure."""
    exit_status = "WARN"
 
 
class UnhandledTestError(TestError):
    """Indicates an unhandled error in a test."""
    def __init__(self, unhandled_exception):
        if isinstance(unhandled_exception, TestError):
            TestError.__init__(self, *unhandled_exception.args)
        elif isinstance(unhandled_exception, basestring):
            TestError.__init__(self, unhandled_exception)
        else:
            msg = "Unhandled %s: %s"
            msg %= (unhandled_exception.__class__.__name__,
                    unhandled_exception)
            msg += "\n" + traceback.format_exc()
            TestError.__init__(self, msg)
 
 
class UnhandledTestFail(TestFail):
    """Indicates an unhandled fail in a test."""
    def __init__(self, unhandled_exception):
        if isinstance(unhandled_exception, TestFail):
            TestFail.__init__(self, *unhandled_exception.args)
        elif isinstance(unhandled_exception, basestring):
            TestFail.__init__(self, unhandled_exception)
        else:
            msg = "Unhandled %s: %s"
            msg %= (unhandled_exception.__class__.__name__,
                    unhandled_exception)
            msg += "\n" + traceback.format_exc()
            TestFail.__init__(self, msg)
 
 
class CmdError(TestError):
    """Indicates that a command failed, is fatal to the test unless caught."""
    def __init__(self, command, result_obj, additional_text=None):
        TestError.__init__(self, command, result_obj, additional_text)
        self.command = command
        self.result_obj = result_obj
        self.additional_text = additional_text
 
    def __str__(self):
        if self.result_obj.exit_status is None:
            msg = "Command <%s> failed and is not responding to signals"
            msg %= self.command
        else:
            msg = "Command <%s> failed, rc=%d"
            msg %= (self.command, self.result_obj.exit_status)
 
        if self.additional_text:
            msg += ", " + self.additional_text
        msg += '\n' + repr(self.result_obj)
        return msg
 
    def __eq__(self, other):
        if type(self) == type(other):
            return (self.command == other.command
                    and self.result_obj == other.result_obj
                    and self.additional_text == other.additional_text)
        else:
            return NotImplemented
 
 
class CmdTimeoutError(CmdError):
    """Indicates that a command timed out."""
 
 
class PackageError(TestError):
    """Indicates an error trying to perform a package operation."""
 
 
class BarrierError(JobError):
    """Indicates an error happened during a barrier operation."""
 
 
class BarrierAbortError(BarrierError):
    """Indicate that the barrier was explicitly aborted by a member."""
 
 
class InstallError(JobError):
    """Indicates an installation error which Terminates and fails the job."""
 
 
class AutotestRunError(AutotestError):
    """Indicates a problem running server side control files."""
 
 
class AutotestTimeoutError(AutotestError):
    """This exception is raised when an autotest test exceeds the timeout
    parameter passed to run_timed_test and is killed.
    """
 
 
class GenericHostRunError(Exception):
    """Indicates a problem in the host run() function running in either client
    or server code.
 
    Should always be constructed with a tuple of two args (error description
    (str), run result object). This is a common class used to create the client
    and server side versions of it when the distinction is useful.
    """
    def __init__(self, description, result_obj):
        self.description = description
        self.result_obj = result_obj
        Exception.__init__(self, description, result_obj)
 
    def __str__(self):
        return self.description + '\n' + repr(self.result_obj)
 
 
class HostInstallTimeoutError(JobError):
    """
    Indicates the machine failed to be installed after the predetermined
    timeout.
    """
 
 
class AutotestHostRunError(GenericHostRunError, AutotestError):
    pass
 
 
class AutotestHostRunCmdError(AutotestHostRunError):
    """Indicates that the command run via Host.run failed.
 
    This is equivalent to CmdError when raised from a Host object instead of
    directly on the DUT using utils.run
    """
 
    def __init__(self, command, result_obj, additional_text=''):
        description = command
        if additional_text:
            description += ' (%s)' % additional_text
        super(AutotestHostRunCmdError, self).__init__(description, result_obj)
        self.command = command
        self.additional_text = additional_text
 
 
class AutotestHostRunTimeoutError(AutotestHostRunCmdError):
    """Indicates that a command run via Host.run timed out.
 
    This is equivalent to CmdTimeoutError when raised from a Host object instead
    of directly on the DUT using utils.run
    """
 
 
# server-specific errors
 
class AutoservError(Exception):
    pass
 
 
class AutoservSSHTimeout(AutoservError):
    """SSH experienced a connection timeout"""
 
 
class AutoservRunError(GenericHostRunError, AutoservError):
    pass
 
 
class AutoservSshPermissionDeniedError(AutoservRunError):
    """Indicates that a SSH permission denied error was encountered."""
 
 
class AutoservUnsupportedError(AutoservError):
    """Error raised when you try to use an unsupported optional feature"""
 
 
class AutoservHostError(AutoservError):
    """Error reaching a host"""
 
 
class AutoservHostIsShuttingDownError(AutoservHostError):
    """Host is shutting down"""
 
 
class AutoservNotMountedHostError(AutoservHostError):
    """Found unmounted partitions that should be mounted"""
 
 
class AutoservSshPingHostError(AutoservHostError):
    """SSH ping failed"""
 
 
class AutoservDiskFullHostError(AutoservHostError):
    """Not enough free disk space on host"""
 
    def __init__(self, path, want_gb, free_space_gb):
        super(AutoservDiskFullHostError, self).__init__(
            'Not enough free space on %s - %.3fGB free, want %.3fGB' %
                    (path, free_space_gb, want_gb))
        self.path = path
        self.want_gb = want_gb
        self.free_space_gb = free_space_gb
 
 
class AutoservNoFreeInodesError(AutoservHostError):
    """Not enough free i-nodes on host"""
 
    def __init__(self, path, want_inodes, free_inodes):
        super(AutoservNoFreeInodesError, self).__init__(
            'Not enough free inodes on %s - %d free, want %d' %
                    (path, free_inodes, want_inodes))
        self.path = path
        self.want_inodes = want_inodes
        self.free_inodes = free_inodes
 
 
class AutoservHardwareHostError(AutoservHostError):
    """Found hardware problems with the host"""
 
 
class AutoservRebootError(AutoservError):
    """Error occured while rebooting a machine"""
 
 
class AutoservShutdownError(AutoservRebootError):
    """Error occured during shutdown of machine"""
 
 
class AutoservSuspendError(AutoservRebootError):
    """Error occured while suspending a machine"""
 
 
class AutoservSubcommandError(AutoservError):
    """Indicates an error while executing a (forked) subcommand"""
    def __init__(self, func, exit_code):
        AutoservError.__init__(self, func, exit_code)
        self.func = func
        self.exit_code = exit_code
 
    def __str__(self):
        return ("Subcommand %s failed with exit code %d" %
                (self.func, self.exit_code))
 
 
class AutoservRepairTotalFailure(AutoservError):
    """Raised if all attempts to repair the DUT failed."""
 
 
class AutoservInstallError(AutoservError):
    """Error occured while installing autotest on a host"""
 
 
class AutoservPidAlreadyDeadError(AutoservError):
    """Error occured by trying to kill a nonexistant PID"""
 
 
# packaging system errors
 
class PackagingError(AutotestError):
    'Abstract error class for all packaging related errors.'
 
 
class PackageUploadError(PackagingError):
    'Raised when there is an error uploading the package'
 
 
class PackageFetchError(PackagingError):
    'Raised when there is an error fetching the package'
 
 
class PackageRemoveError(PackagingError):
    'Raised when there is an error removing the package'
 
 
class PackageInstallError(PackagingError):
    'Raised when there is an error installing the package'
 
 
class RepoDiskFullError(PackagingError):
    'Raised when the destination for packages is full'
 
 
class RepoWriteError(PackagingError):
    "Raised when packager cannot write to a repo's desitnation"
 
 
class RepoUnknownError(PackagingError):
    "Raised when packager cannot write to a repo's desitnation"
 
 
class RepoError(PackagingError):
    "Raised when a repo isn't working in some way"
 
 
class StageControlFileFailure(Exception):
    """Exceptions encountered staging control files."""
 
 
class CrosDynamicSuiteException(Exception):
    """
    Base class for exceptions coming from dynamic suite code in
    server/cros/dynamic_suite/*.
    """
 
 
class StageBuildFailure(CrosDynamicSuiteException):
    """Raised when the dev server throws 500 while staging a build."""
 
 
class ControlFileEmpty(CrosDynamicSuiteException):
    """Raised when the control file exists on the server, but can't be read."""
 
 
class ControlFileMalformed(CrosDynamicSuiteException):
    """Raised when an invalid control file is read."""
 
 
class AsynchronousBuildFailure(CrosDynamicSuiteException):
    """Raised when the dev server throws 500 while finishing staging of a build.
    """
 
 
class SuiteArgumentException(CrosDynamicSuiteException):
    """Raised when improper arguments are used to run a suite."""
 
 
class MalformedDependenciesException(CrosDynamicSuiteException):
    """Raised when a build has a malformed dependency_info file."""
 
 
class InadequateHostsException(CrosDynamicSuiteException):
    """Raised when there are too few hosts to run a suite."""
 
 
class NoHostsException(CrosDynamicSuiteException):
    """Raised when there are no healthy hosts to run a suite."""
 
 
class ControlFileNotFound(CrosDynamicSuiteException):
    """Raised when a control file cannot be found and/or read."""
 
 
class NoControlFileList(CrosDynamicSuiteException):
    """Raised to indicate that a listing can't be done."""
 
 
class SuiteControlFileException(CrosDynamicSuiteException):
    """Raised when failing to list the contents of all control file."""
 
 
class HostLockManagerReuse(CrosDynamicSuiteException):
    """Raised when a caller tries to re-use a HostLockManager instance."""
 
 
class ReimageAbortedException(CrosDynamicSuiteException):
    """Raised when a Reimage job is aborted"""
 
 
class UnknownReimageType(CrosDynamicSuiteException):
    """Raised when a suite passes in an invalid reimage type"""
 
 
class NoUniquePackageFound(Exception):
    """Raised when an executable cannot be mapped back to a single package."""
 
 
class RPCException(Exception):
    """Raised when an RPC encounters an error that a client might wish to
    handle specially."""
 
 
class NoEligibleHostException(RPCException):
    """Raised when no host could satisfy the requirements of a job."""
 
 
class UnmodifiableLabelException(RPCException):
    """Raised when an RPC tries to modify static labels."""
 
 
class UnmodifiableAttributeException(RPCException):
    """Raised when an RPC tries to modify static attributes."""
 
 
class InvalidBgJobCall(Exception):
    """Raised when an invalid call is made to a BgJob object."""
 
 
class HeartbeatOnlyAllowedInShardModeException(Exception):
    """Raised when a heartbeat is attempted but not allowed."""
 
 
class UnallowedRecordsSentToMaster(Exception):
    """Raised when an illegal record was sent from shard to master."""
 
 
class IgnorableUnallowedRecordsSentToMaster(UnallowedRecordsSentToMaster):
    """Raised when non-fatal illegal record was sent from shard.
 
    This exception may be raised by rpc model logic on master, but will
    not be returned back to heartbeat client. It indicates that some records
    may have been illegal, but the master is ignoring those records and
    proceeding with the rest of the heartbeat handling.
    """
 
 
class InvalidDataError(Exception):
    """Exception raised when invalid data provided for database operation."""
 
 
class ContainerError(Exception):
    """Exception raised when program runs into error using container."""
 
 
class IllegalUser(Exception):
    """Exception raise when a program runs as an illegal user."""
 
 
class AutoservDirectoryNotFoundError(AutoservHostError):
    """Exception raised when an expected directory is not found."""
 
 
class AutoservDiskSizeUnknownError(AutoservHostError):
    """Exception raised when the disk space could not be determined."""
 
 
# This MUST remain at the end of the file.
# Limit 'from error import *' to only import the exception instances.
for _name, _thing in locals().items():
    try:
        if issubclass(_thing, Exception):
            __all__.append(_name)
    except TypeError:
        pass  # _thing not a class
__all__ = tuple(__all__)