2017-04-11 21:25:40 +03:00
|
|
|
# Copyright 2004-present Facebook. All Rights Reserved.
|
|
|
|
|
|
|
|
import errno
|
|
|
|
import os
|
|
|
|
import time
|
|
|
|
import unittest
|
|
|
|
|
|
|
|
import silenttestrunner
|
|
|
|
|
2017-11-30 01:57:10 +03:00
|
|
|
from mercurial import (
|
|
|
|
error,
|
|
|
|
vfs,
|
|
|
|
worker,
|
|
|
|
)
|
|
|
|
|
2018-02-15 07:21:02 +03:00
|
|
|
from hgext import extutil
|
2017-04-11 21:25:40 +03:00
|
|
|
|
2017-11-30 01:57:10 +03:00
|
|
|
locktimeout = 25
|
|
|
|
locksuccess = 24
|
|
|
|
|
2017-04-11 21:25:40 +03:00
|
|
|
class ExtutilTests(unittest.TestCase):
|
|
|
|
def testbgcommandnoblock(self):
|
|
|
|
'''runbgcommand() should return without waiting for the process to
|
|
|
|
finish.'''
|
|
|
|
env = os.environ.copy()
|
|
|
|
start = time.time()
|
|
|
|
extutil.runbgcommand(['sleep', '5'], env)
|
|
|
|
end = time.time()
|
|
|
|
if end - start >= 1.0:
|
|
|
|
self.fail('runbgcommand() took took %s seconds, should have '
|
|
|
|
'returned immediately' % (end - start))
|
|
|
|
|
2018-02-10 04:31:41 +03:00
|
|
|
def testbgcommandfailure1(self):
|
2017-04-11 21:25:40 +03:00
|
|
|
'''runbgcommand() should throw if executing the process fails.'''
|
|
|
|
env = os.environ.copy()
|
|
|
|
try:
|
|
|
|
extutil.runbgcommand(['no_such_program', 'arg1', 'arg2'], env)
|
|
|
|
self.fail('expected runbgcommand to fail with ENOENT')
|
|
|
|
except OSError as ex:
|
|
|
|
self.assertEqual(ex.errno, errno.ENOENT)
|
|
|
|
|
2018-02-10 04:31:41 +03:00
|
|
|
def testbgcommandfailure2(self):
|
2017-04-11 21:25:40 +03:00
|
|
|
'''runbgcommand() should throw if executing the process fails.'''
|
|
|
|
env = os.environ.copy()
|
|
|
|
try:
|
|
|
|
extutil.runbgcommand([os.devnull, 'arg1', 'arg2'], env)
|
|
|
|
self.fail('expected runbgcommand to fail with EACCES')
|
|
|
|
except OSError as ex:
|
|
|
|
self.assertEqual(ex.errno, errno.EACCES)
|
|
|
|
|
2017-12-01 02:58:37 +03:00
|
|
|
def testflock(self):
|
2017-11-30 01:57:10 +03:00
|
|
|
testtmp = os.environ["TESTTMP"]
|
|
|
|
opener = vfs.vfs(testtmp)
|
|
|
|
name = 'testlock'
|
|
|
|
|
2017-12-01 02:58:37 +03:00
|
|
|
with extutil.flock(opener.join(name), 'testing a lock',
|
|
|
|
timeout=0):
|
2017-11-30 01:57:10 +03:00
|
|
|
otherlock = self.otherprocesslock(opener, name)
|
|
|
|
self.assertEquals(otherlock, locktimeout,
|
|
|
|
"other process should not have taken the lock")
|
|
|
|
|
|
|
|
otherlock = self.otherprocesslock(opener, name)
|
|
|
|
self.assertEquals(otherlock, locksuccess,
|
|
|
|
"other process should have taken the lock")
|
|
|
|
|
|
|
|
def otherprocesslock(self, opener, name):
|
|
|
|
pid = os.fork()
|
|
|
|
if pid == 0:
|
|
|
|
try:
|
2017-12-01 02:58:37 +03:00
|
|
|
with extutil.flock(opener.join(name), 'other process lock',
|
|
|
|
timeout=0):
|
2017-11-30 01:57:10 +03:00
|
|
|
os._exit(locksuccess)
|
|
|
|
except error.LockHeld:
|
|
|
|
os._exit(locktimeout)
|
|
|
|
else:
|
|
|
|
p, st = os.waitpid(pid, 0)
|
|
|
|
st = worker._exitstatus(st) # Convert back to an int
|
|
|
|
return st
|
|
|
|
|
2017-04-11 21:25:40 +03:00
|
|
|
if __name__ == '__main__':
|
|
|
|
silenttestrunner.main(__name__)
|