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