xref: /trunk/test/aoo-test/tests/harness/test_prepared.py (revision 85d6e4e58e50c1ed01601e2737a66d9715456246)
1################################################################
2#
3#  Licensed to the Apache Software Foundation (ASF) under one
4#  or more contributor license agreements.  See the NOTICE file
5#  distributed with this work for additional information
6#  regarding copyright ownership.  The ASF licenses this file
7#  to you under the Apache License, Version 2.0 (the
8#  "License"); you may not use this file except in compliance
9#  with the License.  You may obtain a copy of the License at
10#
11#    http://www.apache.org/licenses/LICENSE-2.0
12#
13#  Unless required by applicable law or agreed to in writing,
14#  software distributed under the License is distributed on an
15#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16#  KIND, either express or implied.  See the License for the
17#  specific language governing permissions and limitations
18#  under the License.
19
20"""aootest.documents.Prepared: a script builder runs in an office of its own that is closed afterwards, and one that stalls is run
21once more in a directory of its own; other builders and other failures are not retried."""
22import pytest
23
24from aootest import documents
25from aootest.client import WorkerCrash, WorkerError, WorkerHang
26
27pytestmark = pytest.mark.selftest
28
29SCRIPT = documents.Source("built/base/base-hsqldb.odb", None, "odb", None, ("base", "base-hsqldb.odb"))
30SMALL = documents.Source("built/page-fill/page-fill.odt", None, "odt", None, ("page-fill", "page-fill.odt"))
31
32
33class FakeSession:
34    def __init__(self, outcomes):
35        self.outcomes, self.calls, self.closed = list(outcomes), [], 0
36
37    def call(self, op, args, timeout):
38        self.calls.append((op, args["builder"], args["outdir"], timeout))
39        outcome = self.outcomes.pop(0)
40        if isinstance(outcome, Exception):
41            raise outcome
42        return {"files": []}
43
44    def close(self):
45        self.closed += 1
46
47
48def prepared(tmp_path, shared, own):
49    return documents.Prepared(shared, tmp_path, lambda builder: own)
50
51
52def test_a_script_builder_runs_in_its_own_office_which_is_closed_afterwards(tmp_path):
53    shared, own = FakeSession([]), FakeSession([None])
54    path = prepared(tmp_path, shared, own).file(SCRIPT)
55    assert shared.calls == [] and len(own.calls) == 1 and own.closed == 1
56    assert path == str(tmp_path / "base" / "out" / "base-hsqldb.odb")
57
58
59def test_a_stalled_script_builder_is_run_once_more_in_another_directory(tmp_path):
60    own = FakeSession([WorkerHang("no answer"), None])
61    path = prepared(tmp_path, FakeSession([]), own).file(SCRIPT)
62    assert [c[2] for c in own.calls] == [str(tmp_path / "base" / "out"), str(tmp_path / "base" / "out-retry")]
63    assert own.closed == 2
64    assert path == str(tmp_path / "base" / "out-retry" / "base-hsqldb.odb")
65
66
67def test_a_script_builder_that_stalls_twice_fails_every_time_without_a_third_try(tmp_path):
68    own = FakeSession([WorkerHang("first"), WorkerHang("second")])
69    prep = prepared(tmp_path, FakeSession([]), own)
70    for _ in range(2):
71        with pytest.raises(WorkerHang):
72            prep.file(SCRIPT)
73    assert len(own.calls) == 2
74
75
76@pytest.mark.parametrize("error", [WorkerCrash("died"), WorkerError("uno", "bad")])
77def test_a_crash_or_an_error_is_not_retried(tmp_path, error):
78    own = FakeSession([error])
79    with pytest.raises(type(error)):
80        prepared(tmp_path, FakeSession([]), own).file(SCRIPT)
81    assert len(own.calls) == 1
82
83
84def test_a_small_builder_runs_in_the_shared_office_and_is_not_retried(tmp_path):
85    shared, own = FakeSession([WorkerHang("no answer")]), FakeSession([])
86    with pytest.raises(WorkerHang):
87        prepared(tmp_path, shared, own).file(SMALL)
88    assert len(shared.calls) == 1 and own.calls == []
89