Ejemplo n.º 1
0
    def _testAsynchronousLockWait(self):
        scheduler = global_event_loop()
        tempdir = tempfile.mkdtemp()
        try:
            path = os.path.join(tempdir, 'lock_me')
            lock1 = AsynchronousLock(path=path, scheduler=scheduler)
            lock1.start()
            self.assertEqual(lock1.wait(), os.EX_OK)
            self.assertEqual(lock1.returncode, os.EX_OK)

            # lock2 requires _force_async=True since the portage.locks
            # module is not designed to work as intended here if the
            # same process tries to lock the same file more than
            # one time concurrently.
            lock2 = AsynchronousLock(path=path,
                                     scheduler=scheduler,
                                     _force_async=True,
                                     _force_process=True)
            lock2.start()
            # lock2 should be waiting for lock1 to release
            self.assertEqual(lock2.poll(), None)
            self.assertEqual(lock2.returncode, None)

            lock1.unlock()
            self.assertEqual(lock2.wait(), os.EX_OK)
            self.assertEqual(lock2.returncode, os.EX_OK)
            lock2.unlock()
        finally:
            shutil.rmtree(tempdir)
Ejemplo n.º 2
0
    def _testAsynchronousLockWaitKill(self):
        scheduler = global_event_loop()
        tempdir = tempfile.mkdtemp()
        try:
            path = os.path.join(tempdir, 'lock_me')
            lock1 = AsynchronousLock(path=path, scheduler=scheduler)
            lock1.start()
            self.assertEqual(lock1.wait(), os.EX_OK)
            self.assertEqual(lock1.returncode, os.EX_OK)
            lock2 = AsynchronousLock(path=path,
                                     scheduler=scheduler,
                                     _force_async=True,
                                     _force_process=True)
            lock2.start()
            # lock2 should be waiting for lock1 to release
            self.assertEqual(lock2.poll(), None)
            self.assertEqual(lock2.returncode, None)

            # Kill lock2's process and then check wait() and
            # returncode results. This is intended to simulate
            # a SIGINT sent via the controlling tty.
            self.assertEqual(lock2._imp is not None, True)
            self.assertEqual(lock2._imp._proc is not None, True)
            self.assertEqual(lock2._imp._proc.pid is not None, True)
            lock2._imp._kill_test = True
            os.kill(lock2._imp._proc.pid, signal.SIGTERM)
            self.assertEqual(lock2.wait() == os.EX_OK, False)
            self.assertEqual(lock2.returncode == os.EX_OK, False)
            self.assertEqual(lock2.returncode is None, False)
            lock1.unlock()
        finally:
            shutil.rmtree(tempdir)
Ejemplo n.º 3
0
    def _testAsynchronousLock(self):
        scheduler = global_event_loop()
        tempdir = tempfile.mkdtemp()
        try:
            path = os.path.join(tempdir, 'lock_me')
            for force_async, async_unlock in itertools.product((True, False),
                                                               repeat=2):
                for force_dummy in (True, False):
                    async_lock = AsynchronousLock(path=path,
                                                  scheduler=scheduler,
                                                  _force_async=force_async,
                                                  _force_thread=True,
                                                  _force_dummy=force_dummy)
                    async_lock.start()
                    self.assertEqual(async_lock.wait(), os.EX_OK)
                    self.assertEqual(async_lock.returncode, os.EX_OK)
                    if async_unlock:
                        scheduler.run_until_complete(async_lock.async_unlock())
                    else:
                        async_lock.unlock()

                async_lock = AsynchronousLock(path=path,
                                              scheduler=scheduler,
                                              _force_async=force_async,
                                              _force_process=True)
                async_lock.start()
                self.assertEqual(async_lock.wait(), os.EX_OK)
                self.assertEqual(async_lock.returncode, os.EX_OK)
                if async_unlock:
                    scheduler.run_until_complete(async_lock.async_unlock())
                else:
                    async_lock.unlock()
        finally:
            shutil.rmtree(tempdir)
Ejemplo n.º 4
0
    def _testAsynchronousLock(self):
        scheduler = PollScheduler().sched_iface
        tempdir = tempfile.mkdtemp()
        try:
            path = os.path.join(tempdir, 'lock_me')
            for force_async in (True, False):
                for force_dummy in (True, False):
                    async_lock = AsynchronousLock(path=path,
                                                  scheduler=scheduler,
                                                  _force_async=force_async,
                                                  _force_thread=True,
                                                  _force_dummy=force_dummy)
                    async_lock.start()
                    self.assertEqual(async_lock.wait(), os.EX_OK)
                    self.assertEqual(async_lock.returncode, os.EX_OK)
                    async_lock.unlock()

                async_lock = AsynchronousLock(path=path,
                                              scheduler=scheduler,
                                              _force_async=force_async,
                                              _force_process=True)
                async_lock.start()
                self.assertEqual(async_lock.wait(), os.EX_OK)
                self.assertEqual(async_lock.returncode, os.EX_OK)
                async_lock.unlock()

        finally:
            shutil.rmtree(tempdir)
Ejemplo n.º 5
0
    def _testAsynchronousLockWaitCancel(self):
        scheduler = global_event_loop()
        tempdir = tempfile.mkdtemp()
        try:
            path = os.path.join(tempdir, 'lock_me')
            lock1 = AsynchronousLock(path=path, scheduler=scheduler)
            lock1.start()
            self.assertEqual(lock1.wait(), os.EX_OK)
            self.assertEqual(lock1.returncode, os.EX_OK)
            lock2 = AsynchronousLock(path=path,
                                     scheduler=scheduler,
                                     _force_async=True,
                                     _force_process=True)
            lock2.start()
            # lock2 should be waiting for lock1 to release
            self.assertEqual(lock2.poll(), None)
            self.assertEqual(lock2.returncode, None)

            # Cancel lock2 and then check wait() and returncode results.
            lock2.cancel()
            self.assertEqual(lock2.wait() == os.EX_OK, False)
            self.assertEqual(lock2.returncode == os.EX_OK, False)
            self.assertEqual(lock2.returncode is None, False)
            lock1.unlock()
        finally:
            shutil.rmtree(tempdir)
Ejemplo n.º 6
0
    def _testAsynchronousLock(self):
        scheduler = global_event_loop()
        tempdir = tempfile.mkdtemp()
        try:
            path = os.path.join(tempdir, "lock_me")
            for force_async in (True, False):
                for force_dummy in ((False, ) if dummy_threading is None else
                                    (True, False)):
                    async_lock = AsynchronousLock(
                        path=path,
                        scheduler=scheduler,
                        _force_async=force_async,
                        _force_thread=True,
                        _force_dummy=force_dummy,
                    )
                    async_lock.start()
                    self.assertEqual(async_lock.wait(), os.EX_OK)
                    self.assertEqual(async_lock.returncode, os.EX_OK)
                    scheduler.run_until_complete(async_lock.async_unlock())

                async_lock = AsynchronousLock(
                    path=path,
                    scheduler=scheduler,
                    _force_async=force_async,
                    _force_process=True,
                )
                async_lock.start()
                self.assertEqual(async_lock.wait(), os.EX_OK)
                self.assertEqual(async_lock.returncode, os.EX_OK)
                scheduler.run_until_complete(async_lock.async_unlock())
        finally:
            shutil.rmtree(tempdir)
Ejemplo n.º 7
0
    def lock(self):
        """
		This raises an AlreadyLocked exception if lock() is called
		while a lock is already held. In order to avoid this, call
		unlock() or check whether the "locked" attribute is True
		or False before calling lock().
		"""
        if self._lock_obj is not None:
            raise self.AlreadyLocked((self._lock_obj, ))

        dir_path = self.settings.get('PORTAGE_BUILDDIR')
        if not dir_path:
            raise AssertionError('PORTAGE_BUILDDIR is unset')
        catdir = os.path.dirname(dir_path)
        self._catdir = catdir

        try:
            portage.util.ensure_dirs(os.path.dirname(catdir),
                                     gid=portage.portage_gid,
                                     mode=0o70,
                                     mask=0)
        except PortageException:
            if not os.path.isdir(os.path.dirname(catdir)):
                raise
        catdir_lock = AsynchronousLock(path=catdir, scheduler=self.scheduler)
        catdir_lock.start()
        catdir_lock.wait()
        self._assert_lock(catdir_lock)

        try:
            try:
                portage.util.ensure_dirs(catdir,
                                         gid=portage.portage_gid,
                                         mode=0o70,
                                         mask=0)
            except PortageException:
                if not os.path.isdir(catdir):
                    raise
            builddir_lock = AsynchronousLock(path=dir_path,
                                             scheduler=self.scheduler)
            builddir_lock.start()
            builddir_lock.wait()
            self._assert_lock(builddir_lock)
            self._lock_obj = builddir_lock
            self.settings['PORTAGE_BUILDIR_LOCKED'] = '1'
        finally:
            self.locked = self._lock_obj is not None
            catdir_lock.unlock()
Ejemplo n.º 8
0
    def async_lock(self):
        """
		This raises an AlreadyLocked exception if lock() is called
		while a lock is already held. In order to avoid this, call
		unlock() or check whether the "locked" attribute is True
		or False before calling lock().
		"""
        if self._lock_obj is not None:
            raise self.AlreadyLocked((self._lock_obj, ))

        result = self.scheduler.create_future()

        def acquired_lock(async_lock):
            if async_lock.wait() == os.EX_OK:
                self.locked = True
                result.set_result(None)
            else:
                result.set_exception(
                    AssertionError(
                        "AsynchronousLock failed with returncode %s" %
                        (async_lock.returncode, )))

        self._lock_obj = AsynchronousLock(path=self.pkg_path,
                                          scheduler=self.scheduler)
        self._lock_obj.addExitListener(acquired_lock)
        self._lock_obj.start()
        return result
Ejemplo n.º 9
0
    def async_unlock(self):
        """
		Release the lock asynchronously. Release notification is available
		via the add_done_callback method of the returned Future instance.

		@returns: Future, result is None
		"""
        if self._lock_obj is not None:
            yield self._lock_obj.async_unlock()

            self._lock_obj = None
            self.locked = False
            self.settings.pop('PORTAGE_BUILDDIR_LOCKED', None)
            catdir_lock = AsynchronousLock(path=self._catdir,
                                           scheduler=self.scheduler)
            try:
                yield catdir_lock.async_start()
                yield catdir_lock.async_wait()
            except asyncio.CancelledError:
                if catdir_lock.poll() is None:
                    catdir_lock.cancel()
                raise

            if catdir_lock.returncode == os.EX_OK:
                try:
                    os.rmdir(self._catdir)
                except OSError:
                    pass
                yield catdir_lock.async_unlock()
Ejemplo n.º 10
0
 def builddir_unlocked(future):
     if future.exception() is not None:
         result.set_exception(future.exception())
     else:
         self._lock_obj = None
         self.locked = False
         self.settings.pop('PORTAGE_BUILDDIR_LOCKED', None)
         catdir_lock = AsynchronousLock(path=self._catdir,
                                        scheduler=self.scheduler)
         catdir_lock.addExitListener(catdir_locked)
         catdir_lock.start()
Ejemplo n.º 11
0
    def _start_lock(self):
        if (self.phase in self._locked_phases
                and "ebuild-locks" in self.settings.features):
            eroot = self.settings["EROOT"]
            lock_path = os.path.join(eroot, portage.VDB_PATH + "-ebuild")
            if os.access(os.path.dirname(lock_path), os.W_OK):
                self._ebuild_lock = AsynchronousLock(path=lock_path,
                                                     scheduler=self.scheduler)
                self._start_task(self._ebuild_lock, self._lock_exit)
                return

        self._start_ebuild()
	def unlock(self):
		if self._lock_obj is None:
			return

		self._lock_obj.unlock()
		self._lock_obj = None
		self.locked = False
		self.settings.pop('PORTAGE_BUILDDIR_LOCKED', None)
		catdir_lock = AsynchronousLock(path=self._catdir, scheduler=self.scheduler)
		catdir_lock.start()
		if catdir_lock.wait() == os.EX_OK:
			try:
				os.rmdir(self._catdir)
			except OSError:
				pass
			finally:
				catdir_lock.unlock()
Ejemplo n.º 13
0
    def unlock(self):
        if self._lock_obj is None:
            return

        self._lock_obj.unlock()
        self._lock_obj = None
        self.locked = False
        self.settings.pop('PORTAGE_BUILDIR_LOCKED', None)
        catdir_lock = AsynchronousLock(path=self._catdir,
                                       scheduler=self.scheduler)
        catdir_lock.start()
        if catdir_lock.wait() == os.EX_OK:
            try:
                os.rmdir(self._catdir)
            except OSError as e:
                if e.errno not in (errno.ENOENT, errno.ENOTEMPTY, errno.EEXIST,
                                   errno.EPERM):
                    raise
            finally:
                catdir_lock.unlock()
Ejemplo n.º 14
0
    def lock(self):
        """
		This raises an AlreadyLocked exception if lock() is called
		while a lock is already held. In order to avoid this, call
		unlock() or check whether the "locked" attribute is True
		or False before calling lock().
		"""
        if self._lock_obj is not None:
            raise self.AlreadyLocked((self._lock_obj, ))

        async_lock = AsynchronousLock(path=self.pkg_path,
                                      scheduler=self.scheduler)
        async_lock.start()

        if async_lock.wait() != os.EX_OK:
            # TODO: Use CompositeTask for better handling, like in EbuildPhase.
            raise AssertionError("AsynchronousLock failed with returncode %s" \
             % (async_lock.returncode,))

        self._lock_obj = async_lock
        self.locked = True
Ejemplo n.º 15
0
    def async_lock(self):
        """
		Acquire the lock asynchronously. Notification is available
		via the add_done_callback method of the returned Future instance.

		This raises an AlreadyLocked exception if async_lock() is called
		while a lock is already held. In order to avoid this, call
		async_unlock() or check whether the "locked" attribute is True
		or False before calling async_lock().

		@returns: Future, result is None
		"""
        if self._lock_obj is not None:
            raise self.AlreadyLocked((self._lock_obj, ))

        dir_path = self.settings.get('PORTAGE_BUILDDIR')
        if not dir_path:
            raise AssertionError('PORTAGE_BUILDDIR is unset')
        catdir = os.path.dirname(dir_path)
        self._catdir = catdir
        catdir_lock = AsynchronousLock(path=catdir, scheduler=self.scheduler)
        builddir_lock = AsynchronousLock(path=dir_path,
                                         scheduler=self.scheduler)
        result = self.scheduler.create_future()

        def catdir_locked(catdir_lock):
            try:
                self._assert_lock(catdir_lock)
            except AssertionError as e:
                result.set_exception(e)
                return

            try:
                portage.util.ensure_dirs(catdir,
                                         gid=portage.portage_gid,
                                         mode=0o70,
                                         mask=0)
            except PortageException as e:
                if not os.path.isdir(catdir):
                    result.set_exception(e)
                    return

            builddir_lock.addExitListener(builddir_locked)
            builddir_lock.start()

        def builddir_locked(builddir_lock):
            try:
                self._assert_lock(builddir_lock)
            except AssertionError as e:
                catdir_lock.async_unlock.add_done_callback(
                    functools.partial(catdir_unlocked, exception=e))
                return

            self._lock_obj = builddir_lock
            self.locked = True
            self.settings['PORTAGE_BUILDDIR_LOCKED'] = '1'
            catdir_lock.async_unlock().add_done_callback(catdir_unlocked)

        def catdir_unlocked(future, exception=None):
            if not (exception is None and future.exception() is None):
                result.set_exception(exception or future.exception())
            else:
                result.set_result(None)

        try:
            portage.util.ensure_dirs(os.path.dirname(catdir),
                                     gid=portage.portage_gid,
                                     mode=0o70,
                                     mask=0)
        except PortageException:
            if not os.path.isdir(os.path.dirname(catdir)):
                raise

        catdir_lock.addExitListener(catdir_locked)
        catdir_lock.start()
        return result
Ejemplo n.º 16
0
    def async_lock(self):
        """
		Acquire the lock asynchronously. Notification is available
		via the add_done_callback method of the returned Future instance.

		This raises an AlreadyLocked exception if async_lock() is called
		while a lock is already held. In order to avoid this, call
		async_unlock() or check whether the "locked" attribute is True
		or False before calling async_lock().

		@returns: Future, result is None
		"""
        if self._lock_obj is not None:
            raise self.AlreadyLocked((self._lock_obj, ))

        dir_path = self.settings.get('PORTAGE_BUILDDIR')
        if not dir_path:
            raise AssertionError('PORTAGE_BUILDDIR is unset')
        catdir = os.path.dirname(dir_path)
        self._catdir = catdir

        try:
            portage.util.ensure_dirs(os.path.dirname(catdir),
                                     gid=portage.portage_gid,
                                     mode=0o70,
                                     mask=0)
        except PortageException:
            if not os.path.isdir(os.path.dirname(catdir)):
                raise

        catdir_lock = AsynchronousLock(path=catdir, scheduler=self.scheduler)
        builddir_lock = AsynchronousLock(path=dir_path,
                                         scheduler=self.scheduler)
        try:
            yield catdir_lock.async_start()
            yield catdir_lock.async_wait()

            self._assert_lock(catdir_lock)

            try:
                portage.util.ensure_dirs(catdir,
                                         gid=portage.portage_gid,
                                         mode=0o70,
                                         mask=0)
            except PortageException:
                if not os.path.isdir(catdir):
                    raise

            yield builddir_lock.async_start()
            yield builddir_lock.async_wait()
        except asyncio.CancelledError:
            if catdir_lock.poll() is None:
                catdir_lock.cancel()
            if builddir_lock.poll() is None:
                builddir_lock.cancel()
            raise

        try:
            self._assert_lock(builddir_lock)
        except AssertionError:
            yield catdir_lock.async_unlock()
            raise

        self._lock_obj = builddir_lock
        self.locked = True
        self.settings['PORTAGE_BUILDDIR_LOCKED'] = '1'
        yield catdir_lock.async_unlock()