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
|
# Copyright (C) 2017 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
package QtQA::Proc::Reliable::Strategy;
use strict;
use warnings;
use Class::Factory::Util;
sub new
{
my ($class) = @_;
return bless {}, $class;
}
# Strategies are expected to override these as appropriate.
sub about_to_run {}
sub process_stdout {}
sub process_stderr {}
# should_retry omitted - no suitable default implementation,
# the strategy is 100% pointless if it does not implement this
=head1 NAME
QtQA::Proc::Reliable::Strategy - base class for QtQA::Proc::Reliable retry logic
=head1 SYNOPSIS
package QtQA::Proc::Reliable::Strategy::GCC;
use base qw(QtQA::Proc::Reliable::Strategy);
# retry on any internal compiler errors, a maximum of 5 times
sub new {
my ($class) = @_;
my $self = $class->SUPER::new();
$self->{ internal_compiler_error } = 0; # whether or not we've seen an ICE
$self->{ run_count } = 0; # how many times we've run
return bless $self, $class;
}
sub about_to_run {
my ($self) = @_;
$self->{ run_count }++;
$self->{ internal_compiler_error } = 0;
}
sub process_stderr {
my ($self, $text) = @_;
$self->{ internal_compiler_error }++ if ($text =~ m{^internal compiler error: }ms);
}
sub should_retry {
my ($self) = @_;
return ($self->{ run_count } < 5 && $self->{ internal_compiler_error });
}
Implement a reliable strategy for any command run via L<QtQA::Proc::Reliable>.
=head1 DESCRIPTION
Reliable strategies for use with L<QtQA::Proc::Reliable> are implemented by subclassing
this module.
=head2 STRATEGY LOOKUP
L<QtQA::Proc::Reliable> decides which strategies are used based on the options passed
during construction. In the default case (automatic strategy selection), the strategy
class follows the name of the command being invoked.
Below are a few examples to clarify.
EXAMPLE: STRATEGIES:
'git', 'fetch' => QtQA::Proc::Reliable::Strategy::Git
{reliable=>1}, 'git', 'fetch' => QtQA::Proc::Reliable::Strategy::Git
{reliable=>['foo', 'bar' ]}, 'git' => QtQA::Proc::Reliable::Strategy::Foo,
QtQA::Proc::Reliable::Strategy::Bar
{reliable=>0}, 'git', 'fetch' => (none)
=head1 METHODS
=over
=item B<new>()
Create and return the object as a reference to a blessed hash.
=item B<process_stdout>(TEXT)
This method is called once per line of standard output (TEXT).
=item B<process_stderr>(TEXT)
This method is called once per line of standard error (TEXT).
=item B<should_retry>()
If a command fails, QtQA::Proc::Reliable will call this function on the strategy
to decide if the command should be retried.
If the command should not be retried, this function should return a false value.
If the command should be retried, this function should return a human-readable
string describing the reason for retrying the command.
=item B<about_to_run>()
This function is called prior to each time QtQA::Proc::Reliable runs the command.
It may be called several times.
This will typically be used to increment an "attempt" counter or to reset some state
relating to the parsing of the command's output.
=back
=head1 SEE ALSO
L<QtQA::Proc::Reliable>, B<exe> function in L<QtQA::TestScript>
=cut
1;
|