[pitivi] Misc fixes to make test_pipeline and test_pipeline_action pass again.



commit cf018399d8d4858b14a63b7e4de900475b3635d7
Author: Alessandro Decina <alessandro decina collabora co uk>
Date:   Wed Mar 18 13:32:10 2009 +0100

    Misc fixes to make test_pipeline and test_pipeline_action pass again.
---
 pitivi/action.py              |   23 +++++++++++++++++++++--
 pitivi/pipeline.py            |   20 +++++++++++---------
 pitivi/signalinterface.py     |    2 ++
 pitivi/stream.py              |   10 +++++-----
 tests/common.py               |   11 +++++++++--
 tests/test_pipeline.py        |    3 +--
 tests/test_pipeline_action.py |   13 ++++++++-----
 7 files changed, 57 insertions(+), 25 deletions(-)

diff --git a/pitivi/action.py b/pitivi/action.py
index 4d77c21..9f6f41e 100644
--- a/pitivi/action.py
+++ b/pitivi/action.py
@@ -85,6 +85,7 @@ class Action(object, Signallable, Loggable):
         self.pipeline = None
         self._links = [] # list of (producer, consumer, prodstream, consstream)
         self._pending_links = [] # list of links that still need to be connected
+        self._pending_links_elements = []
         self._dyn_links = [] # list of links added at RunTime, will be removed when deactivated
         self._dynconsumers = [] # consumers that we added at RunTime
 
@@ -468,20 +469,24 @@ class Action(object, Signallable, Loggable):
             self.debug("  producer:%r, stream:%s", prod, prodstream)
             self.debug("  consumer:%r, stream:%s", cons, consstream)
             if prod == producer and (prodstream == None or \
-                    prodstream.isCompatibleWithName(stream)):
+                    prodstream.isCompatible(stream)):
                 if self._activateLink(prod, cons, stream, consstream):
+                    self._pending_links_elements.append((prod, stream))
                     waspending = True
                     self.debug("Successfully linked pending stream, removing "
                             "it from temp list")
                     self._pending_links.remove((prod, cons,
                             prodstream, consstream))
+                    self._pd = getattr(self, '_pd', [])
+                    self._pd.append((producer, stream))
+
 
         if waspending == False:
             self.debug("Checking to see if we haven't already handled it")
             # 2. If it's not one of the pending links, It could also be one of the
             # links we've *already* handled
             for prod, cons, ps, cs in self.getLinks():
-                if prod == producer and ps.isCompatibleWithName(stream):
+                if prod == producer and ps.isCompatible(stream):
                     self.debug("Already handled that link, returning True")
                     return True
 
@@ -597,6 +602,7 @@ class Action(object, Signallable, Loggable):
         try:
             tee = self.pipeline.getTeeForFactoryStream(producer, prodstream,
                                                      automake=True)
+
         except PipelineError:
             if init != True:
                 self.debug("Could not create link")
@@ -632,6 +638,7 @@ class Action(object, Signallable, Loggable):
         self.info("linking the tee to the queue")
         # Link tees to queues
         tee.link(queue)
+
         self.info("done")
         return True
 
@@ -642,8 +649,20 @@ class Action(object, Signallable, Loggable):
             # release tee/queue usage for that stream
             self.pipeline.releaseQueueForFactoryStream(consumer, consstream)
             self.pipeline.releaseBinForFactoryStream(consumer, consstream)
+            try:
+                self.pipeline.releaseTeeForFactoryStream(producer, prodstream)
+            except PipelineError:
+                # FIXME: _really_ create an exception hierarchy
+
+                # this happens if the producer is part of a pending link that
+                # has not been activated yet
+                self.debug("producer has no tee.. pending link?")
+            self.pipeline.releaseBinForFactoryStream(producer, prodstream)
+
+        for producer, prodstream in self._pending_links_elements:
             self.pipeline.releaseTeeForFactoryStream(producer, prodstream)
             self.pipeline.releaseBinForFactoryStream(producer, prodstream)
+        self._pending_links_elements = []
 
         # release dynamic links
         for producer, consumer, prodstream, consstream in self._dyn_links:
diff --git a/pitivi/pipeline.py b/pitivi/pipeline.py
index 24de231..7f76189 100644
--- a/pitivi/pipeline.py
+++ b/pitivi/pipeline.py
@@ -167,10 +167,7 @@ class Pipeline(object, Signallable, Loggable):
         self._listenToPosition(False)
         self._bus.disconnect_by_func(self._busMessageCb)
         self._bus.remove_signal_watch()
-        try:
-            self._bus.set_sync_handler(None)
-        except:
-            self.debug("ignore me")
+        self._bus.set_sync_handler(None)
         self.setState(STATE_NULL)
         self._bus = None
         self._pipeline = None
@@ -471,8 +468,11 @@ class Pipeline(object, Signallable, Loggable):
                     continue
 
                 if stream.isCompatibleWithName(factory_stream):
-                    stream_entry = entry
-                    break
+                    if stream_entry is None:
+                        stream_entry = entry
+                    elif stream is factory_stream:
+                        stream_entry = entry
+                        break
 
         if stream_entry is None:
             if not create:
@@ -628,10 +628,10 @@ class Pipeline(object, Signallable, Loggable):
 
         stream_entry.tee = gst.element_factory_make("tee")
         self._pipeline.add(stream_entry.tee)
+        stream_entry.tee_use_count += 1
         stream_entry.tee.set_state(STATE_PAUSED)
         self.debug("Linking pad %r to tee", pads[0])
         srcpad.link(stream_entry.tee.get_pad("sink"))
-        stream_entry.tee_use_count += 1
 
         return stream_entry.tee
 
@@ -655,15 +655,18 @@ class Pipeline(object, Signallable, Loggable):
         self.debug("factory:%r, stream:%r", factory, stream)
         stream_entry = self._getStreamEntryForFactoryStream(factory, stream)
 
+        if stream_entry.tee_use_count == 0:
+            raise PipelineError()
+
         stream_entry.tee_use_count -= 1
         if stream_entry.tee_use_count == 0:
             bin = self.getBinForFactoryStream(factory, stream, automake=False)
-            self.releaseBinForFactoryStream(factory, stream)
             if stream_entry.tee is not None:
                 bin.unlink(stream_entry.tee)
                 stream_entry.tee.set_state(gst.STATE_NULL)
                 self._pipeline.remove(stream_entry.tee)
                 stream_entry.tee = None
+            self.releaseBinForFactoryStream(factory, stream)
 
     def getQueueForFactoryStream(self, factory, stream=None, automake=False,
                                  queuesize=1):
@@ -879,7 +882,6 @@ class Pipeline(object, Signallable, Loggable):
             for action in [action for action in self.actions
                     if factory in action.producers]:
                 action.streamRemoved(factory, stream)
-            del stream_entry.factory_entry.streams[stream]
         except:
             self._lock.release()
         self._lock.release()
diff --git a/pitivi/signalinterface.py b/pitivi/signalinterface.py
index 9e30c64..9849100 100644
--- a/pitivi/signalinterface.py
+++ b/pitivi/signalinterface.py
@@ -177,6 +177,8 @@ class Signallable:
 
         self._signal_group.disconnect_by_function(function)
 
+    disconnect_by_func = disconnect_by_function
+
     @classmethod
     def get_signals(cls):
         """ Get the full list of signals implemented by this class """
diff --git a/pitivi/stream.py b/pitivi/stream.py
index 7aa640f..54b100e 100644
--- a/pitivi/stream.py
+++ b/pitivi/stream.py
@@ -81,11 +81,11 @@ class MultimediaStream(object, Loggable):
         @return: C{True} if the stream is compatible.
         @rtype: C{bool}
         """
-        if self.pad_name and other.pad_name:
-            self.log("self.pad_name:%r, other.pad_name:%r",
-                     self.pad_name, other.pad_name)
-            return self.pad_name == other.pad_name and self.isCompatible(other)
-        return self.isCompatible(other)
+        #if self.pad_name and other.pad_name:
+        self.log("self.pad_name:%r, other.pad_name:%r",
+                 self.pad_name, other.pad_name)
+        return self.pad_name == other.pad_name and self.isCompatible(other)
+        #return self.isCompatible(other)
 
     def __repr__(self):
         return "<%s(%s) '%s'>" % (self.__class__.__name__,
diff --git a/tests/common.py b/tests/common.py
index 8db306e..4191dcd 100644
--- a/tests/common.py
+++ b/tests/common.py
@@ -82,13 +82,20 @@ class FakeGnlFactory(SourceFactory):
 
 class SignalMonitor(object):
     def __init__(self, obj, *signals):
-        self.obj = obj
+        self.signals = signals
+        self.connectToObj(obj)
 
-        for signal in signals:
+    def connectToObj(self, obj):
+        self.obj = obj
+        for signal in self.signals:
             obj.connect(signal, self._signalCb, signal)
             setattr(self, self._getSignalCounterName(signal), 0)
             setattr(self, self._getSignalCollectName(signal), [])
 
+    def disconnectFromObj(self, obj):
+        obj.disconnect_by_func(self._signalCb)
+        del self.obj
+
     def _getSignalCounterName(self, signal):
         field = '%s_count' % signal.replace('-', '_')
         return field
diff --git a/tests/test_pipeline.py b/tests/test_pipeline.py
index b9b4946..a4a5bd2 100644
--- a/tests/test_pipeline.py
+++ b/tests/test_pipeline.py
@@ -47,8 +47,8 @@ class TestPipeline(TestCase):
     def tearDown(self):
         self.pipeline.setState(STATE_NULL)
         self.pipeline.release()
+        self.monitor.disconnectFromObj(self.pipeline)
         del self.pipeline
-        del self.monitor.obj
         del self.monitor
         TestCase.tearDown(self)
 
@@ -262,7 +262,6 @@ class TestPipeline(TestCase):
         stream2= VideoStream(gst.Caps('any'), 'src')
         factory2.addInputStream(stream2)
 
-        bin1 = self.pipeline.getBinForFactoryStream(factory, stream, True)
         self.failUnlessRaises(PipelineError,
             self.pipeline.getTeeForFactoryStream, factory2, stream2, True)
         self.pipeline.releaseBinForFactoryStream(factory, stream)
diff --git a/tests/test_pipeline_action.py b/tests/test_pipeline_action.py
index 17e2715..5f4b076 100644
--- a/tests/test_pipeline_action.py
+++ b/tests/test_pipeline_action.py
@@ -28,6 +28,7 @@ from unittest import TestCase, main
 from pitivi.pipeline import Pipeline, STATE_READY, STATE_PLAYING, STATE_NULL
 from pitivi.action import Action, STATE_ACTIVE, STATE_NOT_ACTIVE, ActionError
 from pitivi.stream import MultimediaStream, VideoStream
+from common import TestCase
 import common
 import gst
 
@@ -131,22 +132,24 @@ class TestPipelineAction(TestCase):
 
         gst.debug("about to activate action")
         a.activate()
-        # theoretically... there shouldn't only be the source, since
-        # the pad for the source hasn't been created yet (and therefore not
-        # requiring a consumer
-        self.assertEquals(len(list(p._pipeline.elements())), 1)
+        # only the producer and the consumer are created, the other elements are
+        # created dinamically
+        self.assertEquals(len(list(p._pipeline.elements())), 2)
 
         p.setState(STATE_PLAYING)
         time.sleep(1)
         p.getState()
         # and make sure that all other elements were created (4)
+        # FIXME  if it's failing here, run the test a few times trying to raise
+        # the time.sleep() above, it may just be racy...
         self.assertEquals(len(list(p._pipeline.elements())), 4)
 
         a.deactivate()
         p.setState(STATE_NULL)
-
+        self.assertEquals(len(list(p._pipeline.elements())), 0)
         p.release()
 
+
     def testDynamicLink(self):
         a = DynamicAction()
         p = Pipeline()



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]