Package elisa :: Package plugins :: Package good :: Package gstreamer_plugin :: Package tests :: Module test_gst_metadata
[hide private]
[frames] | no frames]

Source Code for Module elisa.plugins.good.gstreamer_plugin.tests.test_gst_metadata

  1  # Elisa - Home multimedia server 
  2  # Copyright (C) 2007-2008 Fluendo Embedded S.L. (www.fluendo.com). 
  3  # All rights reserved. 
  4  # 
  5  # This file is available under one of two license agreements. 
  6  # 
  7  # This file is licensed under the GPL version 3. 
  8  # See "LICENSE.GPL" in the root of this distribution including a special 
  9  # exception to use Elisa with Fluendo's plugins. 
 10  # 
 11  # The GPL part of Elisa is also available under a commercial licensing 
 12  # agreement from Fluendo. 
 13  # See "LICENSE.Elisa" in the root directory of this distribution package 
 14  # for details on that license. 
 15   
 16  __maintainer__ = 'Alessandro Decina <alessandro@fluendo.com>' 
 17   
 18  import gobject 
 19  gobject.threads_init() 
 20  import gst 
 21   
 22  from elisa.core.tests.elisa_test_case import ElisaTestCase 
 23  from elisa.core.tests.component_test_case import ComponentTestCase 
 24  from elisa.core.media_uri import MediaUri 
 25   
 26  from twisted.internet import defer, reactor 
 27  from twisted.python import failure 
 28   
 29  from elisa.plugins.good.gstreamer_plugin.gst_metadata import \ 
 30          GstMetadataPipeline, MetadataClientProcessLauncher, TimeoutError 
 31   
32 -class GPropsProxy(object):
33 - def __init__(self, gprops):
34 self.__dict__['gprops'] = gprops
35
36 - def __setattr__(self, name, value):
37 if name == 'location': 38 return 39 40 setattr(self.gprops, name, value)
41
42 -class TestMetadataAudioPipeline(GstMetadataPipeline):
43 - def _build_pipeline(self):
44 GstMetadataPipeline._build_pipeline(self) 45 src = self._src 46 src.unlink(self._typefind) 47 self._pipeline.remove(src) 48 src.set_state(gst.STATE_NULL) 49 src = self._src = gst.element_factory_make('audiotestsrc') 50 identity = self._identity = gst.element_factory_make('identity') 51 src.props = GPropsProxy(src.props) 52 self._pipeline.add(src, identity) 53 gst.element_link_many(src, identity, self._typefind) 54 src.set_state(gst.STATE_READY) 55 identity.set_state(gst.STATE_READY)
56
57 -class TestMetadataVideoPipeline(GstMetadataPipeline):
58 - def _build_pipeline(self):
59 GstMetadataPipeline._build_pipeline(self) 60 src = self._src 61 src.unlink(self._typefind) 62 self._pipeline.remove(src) 63 src.set_state(gst.STATE_NULL) 64 src = self._src = gst.element_factory_make('videotestsrc') 65 identity = self._identity = gst.element_factory_make('identity') 66 src.props = GPropsProxy(src.props) 67 self._pipeline.add(src, identity) 68 gst.element_link_many(src, identity, self._typefind) 69 src.set_state(gst.STATE_READY) 70 identity.set_state(gst.STATE_READY) 71 self._have_thumbnail = False
72
73 - def _have_video_thumbnail(self):
74 # toggle _have_thumbnail so that we go to PAUSED and then stop on the 75 # first frame 76 self._have_thumbnail = not self._have_thumbnail 77 return not self._have_thumbnail
78
79 -class TestGstMetadataPipelineCommon(object):
80 """Whitebox tests for GstMetadataPipeline"""
81 - def setUpClass(self):
82 self.audio_pipeline = self.build_audio_pipeline() 83 self.video_pipeline = self.build_video_pipeline() 84 self.audio_pipeline.initialize() 85 self.video_pipeline.initialize()
86
87 - def tearDownClass(self):
88 self.audio_pipeline.clean() 89 self.video_pipeline.clean()
90
92 def get_metadata_done(result): 93 self.assertEqual(result['file_type'], 'audio')
94 95 media_type_dict = {'uri': MediaUri('file://not_used_for_the_test'), 96 'file_type': None, 'mime_type': None} 97 dfr = self.audio_pipeline.get_metadata(media_type_dict) 98 dfr.addCallback(get_metadata_done) 99 100 return dfr
101
102 - def test_get_video_media_type(self):
103 media_type_dict = {'uri': MediaUri('file://not_used_for_the_test'), 104 'file_type': None, 'mime_type': None} 105 dfr = self.video_pipeline.get_metadata(media_type_dict) 106 107 def get_metadata_done(result): 108 self.assertEqual(result['file_type'], 'video')
109 110 dfr.addCallback(get_metadata_done) 111 112 return dfr 113
114 - def _eat_buffers_probe_cb(self, buffer, data):
115 return False
116
117 - def test_metadata_timeout(self):
118 pad = self.audio_pipeline._src.get_pad('src') 119 probe_id = pad.add_buffer_probe(self._eat_buffers_probe_cb) 120 121 def get_metadata_result(result): 122 pad.remove_buffer_probe(probe_id) 123 self.failUnless(isinstance(result, failure.Failure)) 124 result.trap(TimeoutError)
125 126 media_type_dict = {'uri': MediaUri('file://not_used_for_the_test'), 127 'file_type': None, 'media_type': None} 128 dfr = self.audio_pipeline.get_metadata(media_type_dict) 129 dfr.addBoth(get_metadata_result) 130 131 return dfr 132
133 - def test_error(self):
134 self.audio_pipeline._identity.props.error_after = 1 135 136 def get_metadata_result(result): 137 self.audio_pipeline._identity.props.error_after = -1 138 self.failUnless(isinstance(result, failure.Failure))
139 140 media_type_dict = {'uri': MediaUri('file://not_used_for_the_test'), 141 'file_type': None, 'media_type': None} 142 dfr = self.audio_pipeline.get_metadata(media_type_dict) 143 dfr.addBoth(get_metadata_result) 144 145 return dfr 146
147 -class TestGstMetadataPipelineNoReuse(ElisaTestCase, 148 TestGstMetadataPipelineCommon):
149 150 skip = "Messes up with GIL" 151
152 - def build_audio_pipeline(self):
157
158 - def build_video_pipeline(self):
163
164 -class TestGstMetadataPipelineReuse(ElisaTestCase, 165 TestGstMetadataPipelineCommon):
166 167 skip = "Messes up with GIL" 168
169 - def build_audio_pipeline(self):
174
175 - def build_video_pipeline(self):
180
181 -class TestGstMetadataBase(object):
182 - def test_able_to_handle(self):
183 # no uri 184 metadata = {'foo': None} 185 self.failIf(self.component.able_to_handle(metadata)) 186 187 # no uri and supported field 188 metadata = {'song': None} 189 self.failIf(self.component.able_to_handle(metadata)) 190 191 # unsupported uri scheme 192 metadata = {'uri': MediaUri('gopher://')} 193 self.failIf(self.component.able_to_handle(metadata)) 194 195 # unsupported uri scheme with supported empty field 196 metadata = {'uri': MediaUri('gopher://'), 'song': None} 197 self.failIf(self.component.able_to_handle(metadata)) 198 199 # supported uri but no empty field 200 metadata = {'uri': MediaUri('file://'), 'artist': 'fabrizio de andre'} 201 self.failIf(self.component.able_to_handle(metadata)) 202 203 # supported uri but no supported field empty 204 metadata = {'uri': MediaUri('file://'), 'artist': 'fabrizio de andre', 205 'foo': None} 206 self.failIf(self.component.able_to_handle(metadata)) 207 208 # supported uri and supported field empty 209 metadata = {'uri': MediaUri('file://'), 'song': None} 210 self.failUnless(self.component.able_to_handle(metadata))
211
212 -class TestGstMetadata(ComponentTestCase, TestGstMetadataBase):
213 component_class = \ 214 'elisa.plugins.good.gstreamer_plugin.gst_metadata:GstMetadata'
215
216 -class TestGstMetadataClient(ComponentTestCase, TestGstMetadataBase):
217 component_class = \ 218 'elisa.plugins.good.gstreamer_plugin.gst_metadata:GstMetadataClient'
219
220 -class TestMetadataClientProcessLauncher(ElisaTestCase):
221 - def setUp(self):
222 self.launcher = MetadataClientProcessLauncher()
223
224 - def test_start_stop(self):
225 def get_component_done_after_stop(result): 226 self.failUnless(isinstance(result, failure.Failure))
227 228 dfr = self.launcher.startProcess() 229 dfr.addCallback(lambda result: self.launcher.stopProcess()) 230 dfr.addCallback(lambda result: self.launcher.get_component()) 231 dfr.addBoth(get_component_done_after_stop) 232 233 return dfr
234 235
236 - def test_restart(self):
237 """Start the metadata_runner process, kill it and check that a 238 get_component() call still succeeds 239 """ 240 def second_get_component_done(result, test_dfr): 241 dfr = self.launcher.stopProcess() 242 dfr.chainDeferred(test_dfr)
243 244 def continue_after_kill(test_dfr): 245 dfr = self.launcher.get_component() 246 dfr.addCallback(second_get_component_done, test_dfr) 247 248 def get_component_done(component): 249 self.launcher.process.signalProcess('KILL') 250 # continue later so the signal is dispatched 251 dfr = defer.Deferred() 252 reactor.callLater(0.1, continue_after_kill, dfr) 253 254 return dfr 255 256 dfr = self.launcher.startProcess() 257 dfr.addCallback(get_component_done) 258 259 return dfr 260
261 - def test_give_up(self):
262 """Start the process, set max_retries to 0 and kill the process. Check 263 that the launcher gives up after max_retries 264 """ 265 def get_component_result(result, test_dfr): 266 self.failUnless(isinstance(result, failure.Failure)) 267 test_dfr.callback(None)
268 269 def continue_after_kill(test_dfr): 270 dfr = self.launcher.get_component() 271 dfr.addBoth(get_component_result, test_dfr) 272 273 return dfr 274 275 def get_component_done(component): 276 self.launcher.max_retries = 0 277 self.launcher.process.signalProcess('KILL') 278 dfr = defer.Deferred() 279 reactor.callLater(0.1, continue_after_kill, dfr) 280 281 return dfr 282 283 dfr = self.launcher.startProcess() 284 dfr.addCallback(get_component_done) 285 286 return dfr 287