9.29KiB, text/plain; us-ascii; Perl | Statements 192
1
#!/usr/bin/perl
2
3
use strict;
4
use warnings;
5
use Test::More;
6
use Test::Output;
7
use Test::Fatal;
8
use Test::Mock::Time;
9
use Test::Warnings;
10
use File::Temp;
11
12
BEGIN {
13
    unshift @INC, '..';
14
}
15
16
require bmwqemu;
17
18
my $cmds;
19
use Test::MockModule;
20 1
my $mod       = new Test::MockModule('myjsonrpc');
21
my $fake_exit = 0;
22
23
sub fake_send_json {
24
    my ($to_fd, $cmd) = @_;
25
    push(@$cmds, $cmd);
26
}
27
28
sub fake_read_json {
29
    my ($fd) = @_;
30
    my $lcmd = $cmds->[-1];
31
    my $cmd  = $lcmd->{cmd};
32
    if ($cmd eq 'backend_wait_serial') {
33
        my $str = $lcmd->{regexp};
34
        $str =~ s,\\d\+,$fake_exit,;
35
        return {ret => {matched => 1, string => $str}};
36
    }
37
    elsif ($cmd eq 'backend_select_console') {
38
        return {ret => {activated => 0}};
39
    }
40
    elsif ($cmd eq 'backend_is_serial_terminal') {
41
        return {ret => {yesorno => 0}};
42
    }
43
    elsif ($cmd eq 'check_screen') {
44
        return {ret => {found => {needle => 1}}};
45
    }
46
    elsif ($cmd eq 'backend_mouse_hide') {
47
        return {ret => 1};
48
    }
49
    elsif ($cmd eq 'backend_get_last_mouse_set') {
50
        return {ret => {x => -1, y => -1}};
51
    }
52
    else {
53
        print "not implemented \$cmd: $cmd\n";
54
    }
55
    return {};
56
}
57
58
$mod->mock(send_json => \&fake_send_json);
59
$mod->mock(read_json => \&fake_read_json);
60
61
use testapi qw(is_serial_terminal :DEFAULT);
62
use basetest;
63 1
my $mock_basetest = new Test::MockModule('basetest');
64
$mock_basetest->mock(_result_add_screenshot => sub { my ($self, $result) = @_; });
65
$autotest::current_test = basetest->new();
66
67
# we have to mock out wait_screen_change for the type_string tests
68
# that use it, as it doesn't work with the fake send_json and read_json
69 1
my $mod2 = new Test::MockModule('testapi');
70
71
## no critic (ProhibitSubroutinePrototypes)
72
sub fake_wait_screen_change(&@) {
73
    my ($callback, $timeout) = @_;
74
    $callback->() if $callback;
75
}
76
77
$mod2->mock(wait_screen_change => \&fake_wait_screen_change);
78
79
type_string 'hallo';
80
is_deeply($cmds, [{cmd => 'backend_type_string', max_interval => 250, text => 'hallo'}]);
81
$cmds = [];
82
83
type_string 'hallo', 4;
84
is_deeply($cmds, [{cmd => 'backend_type_string', max_interval => 4, text => 'hallo'}]);
85
$cmds = [];
86
87
type_string 'hallo', secret => 1;
88
is_deeply($cmds, [{cmd => 'backend_type_string', max_interval => 250, text => 'hallo'}]);
89
$cmds = [];
90
91
type_string 'hallo', secret => 1, max_interval => 10;
92
is_deeply($cmds, [{cmd => 'backend_type_string', max_interval => 10, text => 'hallo'}]);
93
$cmds = [];
94
95
type_string 'hallo', wait_screen_change => 3;
96
is_deeply($cmds, [{cmd => 'backend_type_string', max_interval => 250, text => 'hal'}, {cmd => 'backend_type_string', max_interval => 250, text => 'lo'},]);
97
$cmds = [];
98
99
type_string 'hallo', wait_screen_change => 2;
100
is_deeply(
101
    $cmds,
102
    [
103
        {cmd => 'backend_type_string', max_interval => 250, text => 'ha'},
104
        {cmd => 'backend_type_string', max_interval => 250, text => 'll'},
105
        {cmd => 'backend_type_string', max_interval => 250, text => 'o'},
106
    ]);
107
$cmds = [];
108
109
type_string 'hallo', wait_screen_change => 3, max_interval => 10;
110
is_deeply($cmds, [{cmd => 'backend_type_string', max_interval => 10, text => 'hal'}, {cmd => 'backend_type_string', max_interval => 10, text => 'lo'},]);
111
$cmds = [];
112
113
subtest 'type_string with wait_still_screen' => sub {
114
    my $wait_still_screen_called = 0;
115 1
    my $module                   = new Test::MockModule('testapi');
116
    $module->mock(wait_still_screen => sub { $wait_still_screen_called = 1; });
117
    type_string 'hallo', wait_still_screen => 1;
118
    is_deeply($cmds, [{cmd => 'backend_type_string', text => 'hallo', max_interval => 250}]);
119
    $cmds = [];
120
    ok($wait_still_screen_called, 'wait still screen should have been called');
121
};
122
123
124
$testapi::password = 'stupid';
125
type_password;
126
is_deeply($cmds, [{cmd => 'backend_type_string', max_interval => 100, text => 'stupid'}]);
127
$cmds = [];
128
129
type_password 'hallo';
130
is_deeply($cmds, [{cmd => 'backend_type_string', max_interval => 100, text => 'hallo'}]);
131
$cmds = [];
132
133
type_password 'hallo', max_interval => 5;
134
is_deeply($cmds, [{cmd => 'backend_type_string', max_interval => 5, text => 'hallo'}]);
135
$cmds = [];
136
137
#$mock_basetest->mock(record_soft_failure_result => sub {});
138 1
my $mock_bmwqemu = new Test::MockModule('bmwqemu');
139
$mock_bmwqemu->mock(result_dir => File::Temp->newdir());
140
141
is($autotest::current_test->{dents}, 0, 'no soft failures so far');
142
stderr_like(\&record_soft_failure, qr/record_soft_failure\(reason=undef\)/, 'soft failure recorded in log');
143
is($autotest::current_test->{dents}, 1, 'soft failure recorded');
144
stderr_like(sub { record_soft_failure('workaround for bug#1234') }, qr/record_soft_failure.*reason=.*workaround for bug#1234.*/, 'soft failure with reason');
145
is($autotest::current_test->{dents}, 2, 'another');
146
my $details = $autotest::current_test->{details}[-1];
147
is($details->{title}, 'Soft Failed', 'title for soft failure added');
148
like($details->{text}, qr/basetest-[0-9]+.*txt/, 'file for soft failure added');
149
150
require distribution;
151
testapi::set_distribution(distribution->new());
152
select_console('a-console');
153
is(is_serial_terminal, 0, 'Not a serial terminal');
154
155
subtest 'script_run' => sub {
156 1
    my $module = new Test::MockModule('bmwqemu');
157
    # just save ourselves some time during testing
158
    $module->mock(wait_for_one_more_screenshot => sub { sleep 0; });
159
160
    $testapi::serialdev = 'null';
161
162
    is(assert_script_run('true'), undef, 'nothing happens on success');
163
    $fake_exit = 1;
164
    like(exception { assert_script_run 'false', 42; }, qr/command.*false.*failed at/, 'with timeout option (deprecated mode)');
165
    like(exception { assert_script_run 'false', 0; },  qr/command.*false.*timed out/, 'exception message distinguishes failed/timed out');
166
    like(
167
        exception { assert_script_run 'false', 7, 'my custom fail message'; },
168
        qr/command.*false.*failed: my custom fail message at/,
169
        'custom message on die (deprecated mode)'
170
    );
171
    like(
172
        exception { assert_script_run('false', fail_message => 'my custom fail message'); },
173
        qr/command.*false.*failed: my custom fail message at/,
174
        'using named arguments'
175
    );
176
    like(
177
        exception { assert_script_run('false', timeout => 0, fail_message => 'my custom fail message'); },
178
        qr/command.*false.*timed out/,
179
        'using two named arguments; fail message does not apply on timeout'
180
    );
181
    $fake_exit = 0;
182
    is(script_run('true'), '0', 'script_run with no check of success, returns exit code');
183
    $fake_exit = 1;
184
    is(script_run('false'), '1', 'script_run with no check of success, returns exit code');
185
    is(script_run('false', 0), undef, 'script_run with no check of success, returns undef when not waiting');
186
};
187
188
subtest 'check_assert_screen' => sub {
189 1
    my $mock_testapi = new Test::MockModule('testapi');
190
    $mock_testapi->mock(_handle_found_needle => sub { return $_[0] });
191
    stderr_like {
192
        is_deeply(assert_screen('foo', 1), {needle => 1}, 'expected and found MATCH reported');
193
    }
194
    qr/assert_screen(.*timeout=1)/;
195
    stderr_like { assert_screen('foo', 3, timeout => 2) } qr/timeout=2/, 'named over positional';
196
    stderr_like { assert_screen('foo') } qr/timeout=30/, 'default timeout';
197
    stderr_like { assert_screen('foo', no_wait => 1) } qr/no_wait=1/, 'no wait option';
198
    stderr_like { check_screen('foo') } qr/timeout=30/, 'check_screen with same default timeout';
199
    stderr_like { check_screen('foo', 42) } qr/timeout=42/, 'check_screen with timeout variable';
200
};
201
202
ok(save_screenshot);
203
204
is(match_has_tag,        undef, 'match_has_tag on no value -> undef');
205
is(match_has_tag('foo'), undef, 'match_has_tag on not matched tag -> undef');
206
subtest 'assert_and_click' => sub {
207 1
    my $mock_testapi = new Test::MockModule('testapi');
208
    $mock_testapi->mock(assert_screen => {area => [{x => 1, y => 2, w => 3, h => 4}]});
209
    ok(assert_and_click('foo'));
210
    is_deeply($cmds->[-1], {cmd => 'backend_mouse_hide', offset => 0}, 'assert_and_click succeeds and hides mouse again -> undef return');
211
};
212
213
subtest 'record_info' => sub {
214
    ok(record_info('my title', "my output\nnext line"), 'simple call');
215
    ok(record_info('my title', 'output', result => 'ok', resultname => 'foo'), 'all arguments');
216
    like(exception { record_info('my title', 'output', result => 'not supported', resultname => 'foo') }, qr/unsupported/, 'invalid result');
217
};
218
219
subtest 'validate_script_output' => sub {
220 1
    my $mock_testapi = new Test::MockModule('testapi');
221
    $mock_testapi->mock(script_output => sub ($;$) { return 'output'; });
222
    ok(!validate_script_output('script', sub { m/output/ }), 'validating output with default timeout');
223
    ok(!validate_script_output('script', sub { m/output/ }, 30), 'specifying timeout');
224
    like(
225
        exception {
226
            validate_script_output('script', sub { m/error/ });
227
        },
228
        qr/output not validating/
229
    );
230
};
231
232
subtest 'wait_still_screen' => sub {
233
    $mod->mock(
234
        read_json => sub {
235
            return {ret => {sim => 999}};
236
        });
237
    ok(wait_still_screen,    'default arguments');
238
    ok(wait_still_screen(3), 'still time specified');
239
    ok(wait_still_screen(2, 4), 'still time and timeout');
240
    ok(wait_still_screen(stilltime => 2, no_wait => 1), 'no_wait option can be specified');
241
    ok(!wait_still_screen(timeout => 4, no_wait => 1), 'two named args, with timeout below stilltime - which will always return false');
242
    ok(wait_still_screen(1, 2, timeout => 3), 'named over positional');
243
};
244
245
done_testing;
246
247
# vim: set sw=4 et: