def testUpdateMapsTrapsPermissionDenied(self): self.mox.StubOutWithMock(map_updater.MapUpdater, 'UpdateFromSource') map_updater.MapUpdater.UpdateFromSource(mox.IgnoreArg(), incremental=True, force_write=False).AndRaise( error.PermissionDenied) self.mox.StubOutClassWithMocks(lock, 'PidFile') lock_mock = lock.PidFile(filename=None) lock_mock.Lock(force=False).AndReturn(True) lock_mock.Locked().AndReturn(True) lock_mock.Unlock() self.conf.maps = [config.MAP_PASSWORD] self.conf.cache = 'dummy' modify_stamp = 1 map_entry = passwd.PasswdMapEntry({'name': 'foo', 'uid': 10, 'gid': 10}) passwd_map = passwd.PasswdMap([map_entry]) passwd_map.SetModifyTimestamp(modify_stamp) source_mock = self.mox.CreateMock(source.Source) self.mox.StubOutWithMock(source_factory, 'Create') source_factory.Create(self.conf.options[ config.MAP_PASSWORD].source).AndReturn(source_mock) cache_mock = self.mox.CreateMock(caches.Cache) self.mox.StubOutWithMock(cache_factory, 'Create') self.mox.ReplayAll() c = command.Update() self.assertEqual( 1, c.UpdateMaps(self.conf, incremental=True, force_write=False))
def testSendTermMatchesCommandAndSendsTerm(self): locker = lock.PidFile() self.mox.StubOutWithMock(locker, '_file', use_mock_anything=True) locker._file.read().AndReturn('1234') locker._file.seek(0) # Mock used in place of an re.compile() pattern -- expects the contents # of our proc_file! mock_re = self.mox.CreateMockAnything() mock_re.match('TEST').AndReturn(True) self.mox.StubOutWithMock(re, 'compile') re.compile('.*nsscache').AndReturn(mock_re) self.mox.StubOutWithMock(os, 'kill') os.kill(1234, signal.SIGTERM) # Create a file we open() in SendTerm(). proc_dir = '%s/1234' % self.workdir proc_filename = '%s/cmdline' % proc_dir os.mkdir(proc_dir) proc_file = open(proc_filename, 'w') proc_file.write('TEST') proc_file.flush() proc_file.close() locker.PROC_DIR = self.workdir self.mox.ReplayAll() locker.SendTerm() os.remove(proc_filename) os.rmdir(proc_dir)
def testLockCreatesPidfiles(self): locker = lock.PidFile() self.mox.StubOutWithMock(locker, '_Open') locker._Open().AndRaise(NotImplementedError) self.mox.ReplayAll() self.assertRaises(NotImplementedError, locker.Lock)
def testUpdateSingleMaps(self): self.mox.StubOutClassWithMocks(lock, 'PidFile') lock_mock = lock.PidFile(filename=None) lock_mock.Lock(force=False).AndReturn(True) lock_mock.Locked().AndReturn(True) lock_mock.Unlock() self.conf.maps = [config.MAP_PASSWORD] self.conf.cache = 'dummy' modify_stamp = 1 map_entry = passwd.PasswdMapEntry({'name': 'foo', 'uid': 10, 'gid': 10}) passwd_map = passwd.PasswdMap([map_entry]) passwd_map.SetModifyTimestamp(modify_stamp) source_mock = self.mox.CreateMock(source.Source) source_mock.GetMap(config.MAP_PASSWORD, location=None).AndReturn(passwd_map) self.mox.StubOutWithMock(source_factory, 'Create') source_factory.Create(self.conf.options[ config.MAP_PASSWORD].source).AndReturn(source_mock) cache_mock = self.mox.CreateMock(caches.Cache) cache_mock.WriteMap(map_data=passwd_map).AndReturn(0) self.mox.StubOutWithMock(cache_factory, 'Create') cache_factory.Create(self.conf.options[config.MAP_PASSWORD].cache, config.MAP_PASSWORD).AndReturn(cache_mock) self.mox.ReplayAll() c = command.Update() self.assertEqual( 0, c.UpdateMaps(self.conf, incremental=True, force_write=False))
def testLockedPredicate(self): locker = lock.PidFile() locker._locked = True self.assertTrue(locker.Locked()) locker._locked = False self.assertFalse(locker.Locked())
def testSendTermNoPid(self): locker = lock.PidFile() self.mox.StubOutWithMock(locker, '_file') locker._file.read().AndReturn('\n') locker.PROC = self.workdir self.mox.ReplayAll() locker.SendTerm()
def testLockStoresPid(self): locker = lock.PidFile(filename=self.filename, pid='PID') locker.Lock() pid_file = open(self.filename, 'r') self.assertEquals(pid_file.read(), 'PID\n') os.remove(self.filename)
def testSendTermNonePid(self): locker = lock.PidFile() self.mox.StubOutWithMock(locker, '_file', use_mock_anything=True) locker._file.read().AndReturn(None) locker.PROC = self.workdir self.mox.ReplayAll() locker.SendTerm()
def testDestructorUnlocks(self): yes = lock.PidFile() self.mox.StubOutWithMock(yes, 'Locked') self.mox.StubOutWithMock(yes, 'Unlock') yes.Locked().AndReturn(True) yes.Unlock() no = lock.PidFile() self.mox.StubOutWithMock(no, 'Locked') no.Locked().AndReturn(False) self.mox.ReplayAll() # test the case where locked returns True. yes.__del__() # test the case where self.Locked() returns False. no.__del__()
def testLockTrapsPermissionDeniedOnly(self): locker = lock.PidFile() self.mox.StubOutWithMock(locker, '_Open') locker._Open().AndRaise(IOError(errno.EACCES, '')) locker._Open().AndRaise(IOError(errno.EIO, '')) self.mox.ReplayAll() self.assertEqual(False, locker.Lock()) self.assertRaises(IOError, locker.Lock)
def testForceLock(self): self.mox.StubOutClassWithMocks(lock, 'PidFile') mock_lock = lock.PidFile(filename=None) mock_lock.Lock(force=True).AndReturn('LOCK') self.mox.ReplayAll() c = command.Command() self.assertEquals('LOCK', c._Lock(force=True))
def testUnlockReleasesFcntlLock(self): locker = lock.PidFile() locker._file = 'FILE_OBJECT' self.mox.StubOutWithMock(fcntl, 'lockf') fcntl.lockf('FILE_OBJECT', fcntl.LOCK_UN) self.mox.ReplayAll() locker.Unlock() self.assertFalse(locker._locked)
def testOpenCreatesAppropriateFileWithPerms(self): locker = lock.PidFile(filename=self.filename) locker._Open() self.assertTrue(os.path.exists(self.filename)) file_mode = os.stat(self.filename)[stat.ST_MODE] correct_mode = (stat.S_IFREG | stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) self.assertEqual(file_mode, correct_mode) os.remove(self.filename)
def testUnlock(self): self.mox.StubOutClassWithMocks(lock, 'PidFile') mock_lock = lock.PidFile(filename=None) mock_lock.Lock(force=False).AndReturn(True) mock_lock.Locked().AndReturn(True) mock_lock.Unlock() mock_lock.Locked().AndReturn(False) # destructor self.mox.ReplayAll() c = command.Command() c._Lock() c._Unlock()
def testUpdateMapsCanForceLock(self): self.mox.StubOutClassWithMocks(lock, 'PidFile') lock_mock = lock.PidFile(filename=None) lock_mock.Lock(force=True).AndReturn(False) lock_mock.Locked().AndReturn(True) lock_mock.Unlock() self.mox.ReplayAll() c = command.Update() self.assertEquals(c.UpdateMaps(self.conf, False, force_lock=True), c.ERR_LOCK)
def testClearLockRemovesPidFile(self): # Create a pid file. pidfile = open(self.filename, 'w') pidfile.write('foo') pidfile.flush() locker = lock.PidFile(filename=self.filename) # Cheat instead of calling open. locker._file = pidfile locker.ClearLock() self.assertFalse(os.path.exists(self.filename))
def testLock(self): self.mox.StubOutClassWithMocks(lock, 'PidFile') mock_lock = lock.PidFile(filename=None) mock_lock.Lock(force=False).AndReturn('LOCK') mock_lock.Lock(force=False).AndReturn('MORLOCK') self.mox.ReplayAll() c = command.Command() # First test that we create a lock and lock it. self.assertEquals('LOCK', c._Lock()) # Then we test that we lock the existing one a second time. self.assertEquals('MORLOCK', c._Lock())
def testSendTermTrapsENOENT(self): locker = lock.PidFile() self.mox.StubOutWithMock(locker, '_file', use_mock_anything=True) locker._file.read().AndReturn('1234\n') locker._file.seek(0) locker.PROC = self.workdir self.mox.StubOutWithMock(builtins, 'open', use_mock_anything=True) builtins.open(mox.IgnoreArg(), 'r').AndRaise(IOError(errno.ENOENT, '')) self.mox.ReplayAll() # self.workdir/1234/cmdline should not exist :) self.assertFalse(os.path.exists('%s/1234/cmdline' % self.workdir)) locker.SendTerm()
def testSendTermTrapsENOENT(self): locker = lock.PidFile() self.mox.StubOutWithMock(locker, '_file') locker._file.read().AndReturn('1234\n') locker._file.seek(0) locker.PROC = self.workdir self.mox.StubOutWithMock(__builtin__, 'open') __builtin__.open(mox.IgnoreArg(), 'r').AndRaise(IOError(errno.ENOENT, '')) self.mox.ReplayAll() # self.workdir/1234/cmdline should not exist :) self.failIf(os.path.exists('%s/1234/cmdline' % self.workdir)) locker.SendTerm()
def testUpdateAutomounts(self): self.mox.StubOutClassWithMocks(lock, 'PidFile') lock_mock = lock.PidFile(filename=None) lock_mock.Lock(force=False).AndReturn(True) lock_mock.Locked().AndReturn(True) lock_mock.Unlock() self.conf.maps = [config.MAP_AUTOMOUNT] self.conf.cache = 'dummy' modify_stamp = 1 map_entry = automount.AutomountMapEntry() map_entry.key = '/home' map_entry.location = 'foo' automount_map = automount.AutomountMap([map_entry]) automount_map.SetModifyTimestamp(modify_stamp) source_mock = self.mox.CreateMock(source.Source) source_mock.GetAutomountMasterMap().AndReturn(automount_map) source_mock.GetMap(config.MAP_AUTOMOUNT, location='foo').AndReturn(automount_map) self.mox.StubOutWithMock(source_factory, 'Create') source_factory.Create(self.conf.options[ config.MAP_PASSWORD].source).AndReturn(source_mock) cache_mock = self.mox.CreateMock(caches.Cache) cache_mock.GetMapLocation().AndReturn('home') cache_mock.WriteMap(map_data=automount_map).AndReturn(0) cache_mock.WriteMap(map_data=automount_map).AndReturn(0) self.mox.StubOutWithMock(cache_factory, 'Create') cache_factory.Create( self.conf.options[config.MAP_AUTOMOUNT].cache, config.MAP_AUTOMOUNT, automount_mountpoint='/home').AndReturn(cache_mock) cache_factory.Create(self.conf.options[config.MAP_AUTOMOUNT].cache, config.MAP_AUTOMOUNT, automount_mountpoint=None).AndReturn(cache_mock) self.mox.ReplayAll() c = command.Update() self.assertEquals( 0, c.UpdateMaps(self.conf, incremental=True, force_write=False))
def testLockLocksWithFcntl(self): locker = lock.PidFile(pid='PID') self.mox.StubOutWithMock(locker, '_file', use_mock_anything=True) locker._file.truncate() locker._file.write('PID\n') locker._file.flush() self.mox.StubOutWithMock(fcntl, 'lockf') fcntl.lockf(locker._file, fcntl.LOCK_EX | fcntl.LOCK_NB) self.mox.ReplayAll() locker.Lock() self.assertTrue(locker._locked) # force __del__ to skip Unlock() locker._locked = False
def testInit(self): locker = lock.PidFile() pid = os.getpid() filename = os.path.basename(sys.argv[0]) filename = '%s/%s' % (locker.STATE_DIR, filename) self.assertTrue(isinstance(locker, lock.PidFile)) self.assertEqual(locker.pid, pid) self.assertEqual(locker.filename, filename) self.assertEqual(locker._locked, False) self.assertEqual(locker._file, None) # also check the case where argv[0] is empty (interactively loaded) full_path = sys.argv[0] sys.argv[0] = '' self.assertRaises(TypeError, lock.PidFile) sys.argv[0] = full_path
def testForceLockTerminatesAndClearsLock(self): locker = lock.PidFile(pid='PID') self.mox.StubOutWithMock(locker, 'SendTerm') locker.SendTerm() self.mox.StubOutWithMock(locker, 'ClearLock') locker.ClearLock() self.mox.StubOutWithMock(locker, '_file') self.mox.StubOutWithMock(fcntl, 'lockf') fcntl.lockf(locker._file, fcntl.LOCK_EX | fcntl.LOCK_NB).AndRaise( IOError(errno.EAGAIN, '')) fcntl.lockf(locker._file, fcntl.LOCK_EX | fcntl.LOCK_NB).AndRaise( IOError(errno.EAGAIN, '')) self.mox.ReplayAll() # This is a little weird due to recursion. # The first time through lockf throws an error and we retry the lock. # The 2nd time through we should fail, because lockf will still throw # an error, so we expect False back and the above mock objects # invoked. self.assertFalse(locker.Lock(force=True))
def _Lock(self, path=None, force=False): """Grab a system-wide lock for this command. Commands wishing to prevent concurrent operation can invoke this method to acquire a system-wide lock. The lock will be automatically released on object destruction, however an optional Unlock() method is provided for commands wishing a smaller scope of locking. Args: path: optional path to lock file. force: optional boolean to override existing locks. Returns: True if the lock was acquired. False if the lock was not. """ # Create the lock if it doesn't exist. if self.lock is None: self.lock = lock.PidFile(filename=path) # Acquire the lock. return self.lock.Lock(force=force)
def testHandleArgumentsProperly(self): filename = 'TEST' pid = 10 locker = lock.PidFile(filename=filename, pid=pid) self.assertEqual(locker.filename, filename) self.assertEqual(locker.pid, pid)