xref: /trunk/test/aoo-test/tests/harness/fake_worker.py (revision 2cb6d6f119bbe2f78742f1c5c8538cb0d4e72ede)
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################################################################
21
22"""A stand-in for the real worker. usage: fake_worker.py <mode>. Modes other than 'good' misbehave in one specific way."""
23import json
24import os
25import signal
26import subprocess
27import sys
28import time
29
30from aootest_worker.proto import Fail, serve
31
32mode = sys.argv[1]
33
34
35def hello(protocol=1):
36    print(json.dumps({"hello": {"protocol": protocol, "python": "3.14.0", "pid": os.getpid()}}), flush=True)
37
38
39def request():
40    return json.loads(sys.stdin.readline())
41
42
43def spawn_child():
44    c = subprocess.Popen([sys.executable, "-c", "import time; time.sleep(120)"])
45    return {"pid": c.pid}
46
47
48def chatter():
49    print("this goes to stderr, not into the protocol")
50    return {"printed": True}
51
52
53OPS = {
54    "echo": lambda **kw: kw,
55    "add": lambda a, b: {"sum": a + b},
56    "sleep": lambda seconds: time.sleep(seconds) or {},
57    "fail": lambda kind, message="": (_ for _ in ()).throw(Fail(kind, message)),
58    "boom": lambda: 1 / 0,
59    "chatter": chatter,
60    "spawn_child": spawn_child,
61    "die139": lambda: os._exit(139),
62    "office-gone": lambda: (_ for _ in ()).throw(Fail("office_dead", "DisposedException: cannot get value ServiceManager")),
63}
64
65if mode == "good":
66    serve(OPS)
67elif mode == "silent":
68    time.sleep(120)
69elif mode == "garbage-hello":
70    print("this is not json", flush=True)
71    time.sleep(120)
72elif mode == "wrong-protocol":
73    hello(99)
74    time.sleep(120)
75elif mode == "exit-before-hello":
76    os._exit(3)
77else:
78    hello()
79    req = request()
80    if mode == "crash139":
81        os._exit(139)
82    elif mode == "sigkill":
83        os.kill(os.getpid(), signal.SIGKILL)
84    elif mode == "stderr-then-crash":
85        print("fatal: the office bridge fell over", file=sys.stderr, flush=True)
86        os._exit(7)
87    elif mode == "garbage-reply":
88        print("garbage", flush=True)
89    elif mode == "not-an-object":
90        print("[1, 2, 3]", flush=True)
91    elif mode == "wrong-id":
92        print(json.dumps({"id": req["id"] + 100, "ok": True, "result": {}}), flush=True)
93    elif mode == "binary-reply":
94        sys.stdout.buffer.write(b"\xff\xfe\x00\n")
95        sys.stdout.buffer.flush()
96    elif mode == "hang":
97        pass
98    else:
99        sys.exit("unknown mode " + mode)
100    time.sleep(120)
101