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