# coding: utf-8

# Copyright (c) 2005-2007 Forest Bond.
# This file is part of the sclapp software package.
# 
# sclapp is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License version 2 as published by the Free
# Software Foundation.
# 
# A copy of the license has been included in the COPYING file.

import os, sys, signal
from unittest import main

from manager import manager

__doc__ = r'''

>>> import os, sclapp, signal
>>> from sclapp import shell

>>> sh = shell.Shell()

>>> sh.execute('false')
Traceback (most recent call last):
...
CommandFailed: ('false', 1, u'')

>>> sh.execute(u'touch ?', u'•')
(0, u'')
>>> sh.execute('rm ?', u'•')
(0, u'')

>>> chars = ''
>>> for ch in sh.follow('echo "foo"; sleep 2'):
...     chars = chars + ch
...     if len(chars) >= 3:
...         sh.interrupt()
Traceback (most recent call last):
...
CommandSignalled: ('echo "foo"; sleep 2', 130, None)

>>> chars = ''
>>> for ch in sh.follow('echo "foo"; sleep 2'):
...     chars = chars + ch
...     if len(chars) >= 3:
...         sh.interrupt()
Traceback (most recent call last):
...
CommandSignalled: ('echo "foo"; sleep 2', 130, None)

Test that commands can be interrupted asynchronously but the shell returns to a
known, usable state:

>>> sclapp.enableSignalHandling(
...   notify_signals = (signal.SIGALRM,),
...   announce_signals = False
... )

>>> signal.alarm(1)
0
>>> sh.execute('sleep 5')
Traceback (most recent call last):
...
SignalError: caught signal 14

>>> sh.execute('echo foo')
(0, u'foo\n')

>>> signal.alarm(1)
0
>>> for ch in sh.follow('sleep 5'): pass
Traceback (most recent call last):
...
SignalError: caught signal 14

>>> sh.execute('echo foo')
(0, u'foo\n')

>>> status = sh.followWrite('yes 2>/dev/null | head -n10')
y
y
y
y
y
y
y
y
y
y
>>> status
0

>>> from sclapp.pipes import pipeFns

>>> status, output = sh.execute('echo $LANG')
>>> language, encoding = output.strip().split('.')

# I'd like to test sh.followWrite more thoroughly here, but doctest doesn't
# seem to deal well with non-ascii characters written directly to stdout.
# Consequently, the tests are executed in a separate process:

>>> sh.execute('python _shell_yes_bullet.py >tmpfile.txt')
(0, u'')
>>> f = open('tmpfile.txt', 'r')
>>> unicode(f.read(), encoding)
u'\u2022\n\u2022\n\u2022\n\u2022\n\u2022\n\u2022\n\u2022\n\u2022\n\u2022\n\u2022\n'
>>> f.close()
>>> os.unlink('tmpfile.txt')

>>> chars = [ ]
>>> signal.alarm(3)
0
>>> for ch in sh.follow('echo "foo"; sleep 5'):
...     chars.append(ch)
Traceback (most recent call last):
...
SignalError: caught signal 14
>>> ''.join(chars)
u'foo\n'

>>> sclapp.disableSignalHandling()

Commands can be executed in the background:

>>> sh.execute('yes >/dev/null & pid=$!')
(0, u'')
>>> status, output = sh.execute('ps $pid')
>>> output.strip().endswith('yes')
True
>>> sh.execute('kill $pid; wait $pid; sleep 1')
(0, u'')
>>> sh.execute('ps $pid')
Traceback (most recent call last):
...
CommandFailed: ('ps $pid', 1, u'  PID TTY      STAT   TIME COMMAND\n')
'''

manager.add_doc_test_cases_from_string(
  __name__,
  globs = globals(),
  name = __name__,
)
