Esempio n. 1
0
def main():
    # build "all signals" list
    allsigv = []
    for attr in dir(syscall):
        if attr.startswith("SIG") and "_" not in attr:
            sig = getattr(syscall, attr)
            if sig not in allsigv: # avoid e.g. SIGCHLD/SIGCLD dups
                allsigv.append(sig)
    allsigv.sort(key=lambda sig: sig.signo)
    allsigv.remove(syscall.SIGKILL) # SIGKILL/SIGSTOP cannot be caught
    allsigv.remove(syscall.SIGSTOP)
    allsigv.remove(syscall.SIGBUS)  # AddressSanitizer crashes on SIGBUS/SIGFPE/SIGSEGV
    allsigv.remove(syscall.SIGFPE)
    allsigv.remove(syscall.SIGSEGV)

    # Notify() -> kill * -> should be notified
    ch = chan(10, dtype=gos.Signal)
    signal.Notify(ch) # all signals
    for sig in allsigv:
        emit("-> %d %s" % (sig.signo, sig))
        killme(sig)
        xsig = ch.recv()
        emit("<- %d %s" % (xsig.signo, xsig))
        if xsig != sig:
            raise AssertionError("got %s, expected %s" % (xsig, sig))
    emit("ok (notify)")

    # Ignore() -> kill * -> should not be notified
    emit()
    signal.Ignore() # all signals
    assert len(ch) == 0
    for sig in allsigv:
        emit("-> %d %s" % (sig.signo, sig))
        killme(sig)
        assert len(ch) == 0
    time.sleep(0.3)
    assert len(ch) == 0
    emit("ok (ignore)")

    # Reset() -> kill * should be handled by OS by default
    emit()
    signal.Reset() # all signals
    emit("terminating ...")
    killme(syscall.SIGTERM)
    raise AssertionError("not terminated")
Esempio n. 2
0
 def _():
     signal.Reset()
Esempio n. 3
0
def test_signal():
    # Notify/Stop with wrong chan dtype -> panic
    _ = panics("pychan: channel type mismatch")
    with _:  signal.Notify(chan(2), syscall.SIGUSR1)
    with _:  signal.Stop  (chan(2))
    with _:  signal.Notify(chan(2, dtype='C.int'), syscall.SIGUSR1)
    with _:  signal.Stop  (chan(2, dtype='C.int'))

    # Notify/Ignore/Reset with wrong signal type
    _ = raises(TypeError)
    with _:  signal.Notify(chan(dtype=gos.Signal), None)
    with _:  signal.Ignore(None)
    with _:  signal.Reset(None)

    # subscribe ch1(USR1), ch12(USR1,USR2) and ch2(USR2)
    ch1  = chan(2, dtype=gos.Signal)
    ch12 = chan(2, dtype=gos.Signal)
    ch2  = chan(2, dtype=gos.Signal)
    signal.Notify(ch1,  syscall.SIGUSR1)
    signal.Notify(ch12, syscall.SIGUSR1, syscall.SIGUSR2)
    signal.Notify(ch2,                   syscall.SIGUSR2)
    def _():
        signal.Reset()
    defer(_)

    for i in range(N):
        # raise SIGUSR1 -> should be delivered to ch1 and ch12
        assert len(ch1)  == 0
        assert len(ch12) == 0
        assert len(ch2)  == 0
        killme(syscall.SIGUSR1)
        waitfor(lambda: len(ch1) == 1 and len(ch12) == 1)
        sig1  = ch1.recv()
        sig12 = ch12.recv()
        assert sig1  == syscall.SIGUSR1
        assert sig12 == syscall.SIGUSR1

        # raise SIGUSR2 -> should be delivered to         ch12 and ch2
        assert len(ch1)  == 0
        assert len(ch12) == 0
        assert len(ch2)  == 0
        killme(syscall.SIGUSR2)
        waitfor(lambda: len(ch12) == 1 and len(ch2) == 1)
        sig12 = ch12.recv()
        sig2  = ch2.recv()
        assert sig12 == syscall.SIGUSR2
        assert sig2  == syscall.SIGUSR2
        # if SIGUSR2 will be eventually delivered to ch1 - it will break
        # in SIGUSR1 check on next iteration.

    # Stop(ch2) -> signals should not be delivered to ch2 anymore
    signal.Stop(ch2)
    for i in range(N):
        # USR1 -> ch1, ch12
        assert len(ch1)  == 0
        assert len(ch12) == 0
        assert len(ch2)  == 0
        killme(syscall.SIGUSR1)
        waitfor(lambda: len(ch1) == 1 and len(ch12) == 1)
        sig1  = ch1.recv()
        sig12 = ch12.recv()
        assert sig1  == syscall.SIGUSR1
        assert sig12 == syscall.SIGUSR1

        # USR2 -> ch12, !ch2
        assert len(ch1)  == 0
        assert len(ch12) == 0
        assert len(ch2)  == 0
        killme(syscall.SIGUSR2)
        waitfor(lambda: len(ch12) == 1)
        sig12 = ch12.recv()
        assert sig12 == syscall.SIGUSR2
        # if SIGUSR2 will be eventually delivered to ch2 - it will break on
        # next iteration.

    # Ignore(USR1) -> ch1 should not be delivered to anymore, ch12 should be delivered only USR2
    signal.Ignore(syscall.SIGUSR1)
    for i in range(N):
        # USR1 -> ø
        assert len(ch1)  == 0
        assert len(ch12) == 0
        assert len(ch2)  == 0
        killme(syscall.SIGUSR1)
        time.sleep(1E-6)

        # USR2 -> ch12
        assert len(ch1)  == 0
        assert len(ch12) == 0
        assert len(ch2)  == 0
        killme(syscall.SIGUSR2)
        waitfor(lambda: len(ch12) == 1)
        sig12 = ch12.recv()
        assert sig12 == syscall.SIGUSR2
        # if SIGUSR1 or SIGUSR2 will be eventually delivered to ch1 or ch2 - it
        # will break on next iteration.

    # Notify after Ignore
    signal.Notify(ch1, syscall.SIGUSR1)
    for i in range(N):
        # USR1 -> ch1
        assert len(ch1)  == 0
        assert len(ch12) == 0
        assert len(ch2)  == 0
        killme(syscall.SIGUSR1)
        waitfor(lambda: len(ch1) == 1)
        sig1 = ch1.recv()
        assert sig1 == syscall.SIGUSR1

        # USR2 -> ch12
        assert len(ch1)  == 0
        assert len(ch12) == 0
        assert len(ch2)  == 0
        killme(syscall.SIGUSR2)
        waitfor(lambda: len(ch12) == 1)
        sig12 = ch12.recv()
        assert sig12 == syscall.SIGUSR2
Esempio n. 4
0
 def _():
     signal.Reset(syscall.SIGINT)
Esempio n. 5
0
def test_stdlib_interop_KeyboardInterrupt():
    # KeyboardInterrupt is raised by default
    with raises(KeyboardInterrupt):
        killme(syscall.SIGINT)
        time.sleep(1)

    ch1 = chan(2, dtype=gos.Signal)
    ch2 = chan(2, dtype=gos.Signal)
    def _():
        signal.Reset(syscall.SIGINT)
    defer(_)

    # Notify disables raising KeyboardInterrupt by default on SIGINT
    signal.Notify(ch1, syscall.SIGINT)
    try:
        killme(syscall.SIGINT)
        waitfor(lambda: len(ch1) == 1)
        obj1 = ch1.recv()
        assert obj1 == syscall.SIGINT
        time.sleep(0.1) # just in case
    except KeyboardInterrupt:
        raise AssertionError("KeyboardInterrupt raised after signal.Notify +ch1")

    signal.Notify(ch2, syscall.SIGINT)
    try:
        killme(syscall.SIGINT)
        waitfor(lambda: len(ch1) == 1 and len(ch2) == 1)
        obj1 = ch1.recv()
        obj2 = ch2.recv()
        assert obj1 == syscall.SIGINT
        assert obj2 == syscall.SIGINT
        time.sleep(0.1) # just in case
    except KeyboardInterrupt:
        raise AssertionError("KeyboardInterrupt raised after signal.Notify +ch1 +ch2")

    # last Stop should reenable raising KeyboardInterrupt by default on SIGINT
    signal.Stop(ch1)
    try:
        killme(syscall.SIGINT)
        waitfor(lambda: len(ch2) == 1)
        obj2 = ch2.recv()
        assert obj2 == syscall.SIGINT
        time.sleep(0.1) # just in case
        assert len(ch1) == 0
    except KeyboardInterrupt:
        raise AssertionError("KeyboardInterrupt raised after signal.Notify +ch1 +ch2 -ch1")

    signal.Stop(ch2)
    with raises(KeyboardInterrupt):
        killme(syscall.SIGINT)
        time.sleep(1)
    time.sleep(0.1) # just in case
    assert len(ch1) == 0
    assert len(ch2) == 0

    # Ignore disables raising KeyboardInterrupt by default on SIGINT
    signal.Ignore(syscall.SIGINT)
    try:
        killme(syscall.SIGINT)
        time.sleep(0.1)
        assert len(ch1) == 0
        assert len(ch2) == 0
    except KeyboardInterrupt:
        raise AssertionError("KeyboardInterrupt raised after signal.Ignore")

    # Reset restores original behaviour
    signal.Reset(syscall.SIGINT)
    with raises(KeyboardInterrupt):
        killme(syscall.SIGINT)
        time.sleep(1)
    time.sleep(0.1) # just in case
    assert len(ch1) == 0
    assert len(ch2) == 0
Esempio n. 6
0
def test_stdlib_interop():
    import signal as pysig

    ch1 = chan(2, dtype=object) # NOTE not gos.Signal nor 'C.os::Signal'
    def _(signo, frame):
        ch1.send("USR1")
    pysig.signal(pysig.SIGUSR1, _)
    def _():
        pysig.signal(pysig.SIGUSR1, pysig.SIG_IGN)
    defer(_)

    # verify that plain pysig delivery works
    for i in range(N):
        assert len(ch1) == 0
        killme(syscall.SIGUSR1)
        waitfor(lambda: len(ch1) == 1)
        obj1 = ch1.recv()
        assert obj1 == "USR1"

    # verify that combined pysig + golang.os.signal delivery works
    ch2 = chan(2, dtype=gos.Signal)
    signal.Notify(ch2, syscall.SIGUSR1)
    def _():
        signal.Stop(ch2)
    defer(_)

    for i in range(N):
        assert len(ch1) == 0
        assert len(ch2) == 0
        killme(syscall.SIGUSR1)
        waitfor(lambda: len(ch1) == 1 and len(ch2) == 1)
        obj1 = ch1.recv()
        sig2 = ch2.recv()
        assert obj1 == "USR1"
        assert sig2 == syscall.SIGUSR1

    # Ignore stops delivery to both pysig and golang.os.signal
    signal.Ignore(syscall.SIGUSR1)
    for i in range(N):
        assert len(ch1) == 0
        assert len(ch2) == 0
        killme(syscall.SIGUSR1)
        time.sleep(1E-6)
    time.sleep(0.1) # just in case
    assert len(ch1) == 0
    assert len(ch2) == 0

    # after Reset pysig delivery is restored even after Ignore
    signal.Reset(syscall.SIGUSR1)
    for i in range(N):
        assert len(ch1) == 0
        assert len(ch2) == 0
        killme(syscall.SIGUSR1)
        waitfor(lambda: len(ch1) == 1)
        assert len(ch2) == 0
        obj1 = ch1.recv()
        assert obj1 == "USR1"

    # Reset stops delivery to golang.os.signal and restores pysig delivery
    signal.Notify(ch2, syscall.SIGUSR1)
    signal.Reset(syscall.SIGUSR1)
    for i in range(N):
        assert len(ch1) == 0
        assert len(ch2) == 0
        killme(syscall.SIGUSR1)
        waitfor(lambda: len(ch1) == 1)
        assert len(ch2) == 0
        obj1 = ch1.recv()
        assert obj1 == "USR1"