aboutsummaryrefslogtreecommitdiffstats
path: root/lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/test/unit/runprocess-scripts.py
blob: 05715cb413c793e25943b924a0d428be20468f44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# This file is part of Buildbot.  Buildbot is free software: you can
# redistribute it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Copyright Buildbot Team Members

# This file contains scripts run by the test_runprocess tests.  Note that since
# this code runs in a different Python interpreter, it does not necessarily
# have access to any of the Buildbot source.  Functions here should be kept
# very simple!

import sys
import os
import time
import select
import signal

# utils

def write_pidfile(pidfile):
    pidfile_tmp = pidfile + "~"
    f = open(pidfile_tmp, "w")
    f.write(str(os.getpid()))
    f.close()
    os.rename(pidfile_tmp, pidfile)

def sleep_forever():
    signal.alarm(110) # die after 110 seconds
    while True:
        time.sleep(10)

def wait_for_parent_death():
    while True:
        ppid = os.getppid()
        if ppid == 1:
            return
        # on some systems, getppid will keep returning
        # a dead pid, so check it for liveness
        try:
            os.kill(ppid, 0)
        except OSError: # Probably ENOSUCH
            return

script_fns = {}
def script(fn):
    script_fns[fn.func_name] = fn
    return fn

# scripts

@script
def write_pidfile_and_sleep():
    pidfile = sys.argv[2]
    write_pidfile(pidfile)
    sleep_forever()

@script
def spawn_child():
    parent_pidfile, child_pidfile = sys.argv[2:]
    if os.fork() == 0:
        write_pidfile(child_pidfile)
    else:
        write_pidfile(parent_pidfile)
    sleep_forever()

@script
def double_fork():
    # when using a PTY, the child process will get SIGHUP when the
    # parent process exits, so ignore that.
    signal.signal(signal.SIGHUP, signal.SIG_IGN)
    parent_pidfile, child_pidfile = sys.argv[2:]
    if os.fork() == 0:
        wait_for_parent_death()
        write_pidfile(child_pidfile)
        sleep_forever()
    else:
        write_pidfile(parent_pidfile)
        sys.exit(0)

@script
def assert_stdin_closed():
    # EOF counts as readable data, so we should see stdin in the readable list,
    # although it may not appear immediately, and select may return early
    bail_at = time.time() + 10
    while True:
        r, w, x = select.select([0], [], [], 0.01)
        if r == [0]: return # succcess!
        if time.time() > bail_at:
            assert False # failure :(

# make sure this process dies if necessary

if not hasattr(signal, 'alarm'):
    signal.alarm = lambda t : None
signal.alarm(110) # die after 110 seconds

# dispatcher

script_fns[sys.argv[1]]()