Index: test/functional/test_copy.py
===================================================================
--- test/functional/test_copy.py (revision 7052)
+++ test/functional/test_copy.py (revision 7054)
@@ -1,6 +1,5 @@
import unittest
import utils
-import shutil
import os
from base import TestBase
@@ -113,5 +112,24 @@
os.unlink(dst_path)
os.rmdir('/tmp/make/')
+ def test_copy_pseudotty(self):
+ """
+ Regression test for DMC-522
+ Trick gfal-copy into thinking it is inside a tty so we trigger some logic that would not
+ be executed otherwise
+ """
+ ffname3 = self.ffname1 + "_copy"
+ self.assertFalse(os.path.isfile(ffname3))
+
+ (ret, out, err) = utils.run_command_pty('gfal-copy', \
+ 'file://' + self.ffname1 + ' file://' + ffname3)
+
+ self.assertTrue(os.path.isfile(ffname3))
+ self.assertNotEqual(len(out), 0) # this makes sure the interactive mode works!
+ self.assertEqual(ret, 0)
+
+ if os.path.isfile(ffname3):
+ os.remove(ffname3)
+
if __name__ == '__main__':
unittest.main()
Index: test/functional/utils.py
===================================================================
--- test/functional/utils.py (revision 7052)
+++ test/functional/utils.py (revision 7054)
@@ -1,6 +1,8 @@
import subprocess
import datetime
import os
+import pty
+import select
import stat
import inspect
@@ -8,22 +10,48 @@
fout = open(path, 'w')
fout.write(os.urandom(size))
fout.close()
-
-
+
+
def create_random_suffix():
return datetime.datetime.now().strftime("%y%m%d_%H%M%S")
def remove_file(path):
os.remove(path)
-
+
def run_command(cmd, args):
script_path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
cmd = script_path + '/../../src/' + cmd
p = subprocess.Popen([cmd] + args.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out,err = p.communicate()
-
+ out, err = p.communicate()
+
return (p.returncode, out, err)
+def run_command_pty(cmd, args):
+ script_path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+ cmd = script_path + '/../../src/' + cmd
+
+ master, slave = pty.openpty()
+ p = subprocess.Popen([cmd] + args.split(), stdout=slave, stderr=slave, close_fds=True)
+ os.close(slave)
+
+ output = ''
+ while True:
+ ready, _, _ = select.select([master], [], [], 1)
+ if ready:
+ try:
+ data = os.read(ready[0], 512)
+ except:
+ data = None
+ if data:
+ output += data
+ else:
+ break
+ os.close(master)
+
+ rstatus = p.wait()
+
+ return (rstatus, output, None)
+
def num_entries(directory):
return len([name for name in os.listdir(directory)])
Index: src/gfal2_util/progress.py
===================================================================
--- src/gfal2_util/progress.py (revision 7052)
+++ src/gfal2_util/progress.py (revision 7054)
@@ -3,7 +3,7 @@
@author: Duarte Meneses <duarte.meneses@cern.ch>
"""
-import os
+import subprocess
import sys
import datetime
import math
@@ -47,8 +47,10 @@
if self.stopped or not self.started:
break
- self._update()
- self.lock.release()
+ try:
+ self._update()
+ finally:
+ self.lock.release()
time.sleep(0.5)
self.lock.release()
@@ -163,7 +165,7 @@
if not self.started:
return
- if self.t_main.is_alive():
+ if self.t_main.isAlive():
self.lock.acquire()
if self.stopped:
self.lock.release()
@@ -194,7 +196,11 @@
@staticmethod
def _get_width():
- return int(os.popen('stty size', 'r').read().split()[1])
+ p = subprocess.Popen(['stty', 'size'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = p.communicate()
+ if p.returncode != 0:
+ return 80 # Asume default
+ return int(out.split()[1])
@staticmethod
def _clean():