def setUp(self): self.rdb = mock_strict_redis_client() self.img = open('data/img.jpg', 'rb').read() self.cf = ImageRefreshCamFeeder(self.rdb, 'wilsat', 'archimedes', 'http://fake.com/image.jpg', 10, 0) # We mock erequests.async.get calls. self.get_patcher = patch('requests.Session.get') self.get_mock = self.get_patcher.start() self.addCleanup(self.get_patcher.stop) fixed_response = requests.Response() fixed_response.status_code = 404 fixed_response.raw = io.BytesIO(b"1234567890"*12) self.get_mock.return_value = fixed_response
class TestBasicException(FeederTestBase): """ Test that if the webcam returns an exception an exception is indeed thrown by the grabber. """ def setUp(self): self.rdb = mock_strict_redis_client() self.img = open('data/img.jpg', 'rb').read() self.cf = ImageRefreshCamFeeder(self.rdb, 'wilsat', 'archimedes', 'http://fake.com/image.jpg', 10, 0) # We mock erequests.async.get calls. self.get_patcher = patch('requests.Session.get') self.get_mock = self.get_patcher.start() self.addCleanup(self.get_patcher.stop) fixed_response = requests.Response() fixed_response.status_code = 404 fixed_response.raw = io.BytesIO(b"1234567890"*12) self.get_mock.return_value = fixed_response def tearDown(self): pass def test_frame_grabbing_exception(self): try: frame = self.cf._grab_frame() self.assertIsNotNone(frame) self.assertGreater(len(frame), 3) self.assertTrue(frame.startswith(b'1234567890')) except FrameGrabbingException as fge: pass else: self.fail('Expected a FrameGrabbingException')
class TestBasic(FeederTestBase): def setUp(self): """ Test that we can grab a single frame and that apprently it returns what we expect. :return: """ self.rdb = mock_strict_redis_client() self._img_file = open('data/img.jpg', 'rb') self.img = self._img_file.read() self.cf = ImageRefreshCamFeeder(self.rdb, 'wilsat', 'archimedes', 'http://fake.com/image.jpg', 10, 0) # We mock requests.get calls. self.get_patcher = patch('requests.Session.get') self.get_mock = self.get_patcher.start() self.addCleanup(self.get_patcher.stop) # Ensure that the request returns fixed_response = requests.Response() fixed_response.status_code = 200 fixed_response.raw = io.BytesIO(b"1234567890"*12) self.get_mock.return_value = fixed_response def tearDown(self): self._img_file.close() def test_grab_frame(self): frame = self.cf._grab_frame() self.assertIsNotNone(frame) self.assertGreater(len(frame), 3) self.assertTrue(frame.startswith(b'1234567890'))
def test_invalid_fps_init_raises(self, get_patch): """ Ensures that trying to initialize with an invalid FPS raises an exception. """ try: self.cf = ImageRefreshCamFeeder(self.rdb, 'wilsat', 'archimedes', 'http://fake.com/image.jpg', 0, 0) except: pass else: self.fail("Exception was expected")
def setUp(self): """ Test that we can grab a single frame and that apprently it returns what we expect. :return: """ self.rdb = mock_strict_redis_client() self._img_file = open('data/img.jpg', 'rb') self.img = self._img_file.read() self.cf = ImageRefreshCamFeeder(self.rdb, 'wilsat', 'archimedes', 'http://fake.com/image.jpg', 10, 0) # We mock requests.get calls. self.get_patcher = patch('requests.Session.get') self.get_mock = self.get_patcher.start() self.addCleanup(self.get_patcher.stop) # Ensure that the request returns fixed_response = requests.Response() fixed_response.status_code = 200 fixed_response.raw = io.BytesIO(b"1234567890"*12) self.get_mock.return_value = fixed_response
def setUp(self): self.rdb = mock_strict_redis_client() self.img = open('data/img.jpg', 'rb').read() self.cf = ImageRefreshCamFeeder(self.rdb, 'wilsat', 'archimedes', 'http://fake.com/image.jpg', 10, 0)
class TestRun(FeederTestBase): """ Complex tests: Lets the frames run. """ def setUp(self): self.rdb = mock_strict_redis_client() self.img = open('data/img.jpg', 'rb').read() self.cf = ImageRefreshCamFeeder(self.rdb, 'wilsat', 'archimedes', 'http://fake.com/image.jpg', 10000, 0) # We mock erequests.async.get calls. self.get_patcher = patch('requests.Session.get') self.get_mock = self.get_patcher.start() self.addCleanup(self.get_patcher.stop) fixed_response = requests.Response() fixed_response.status_code = 200 fixed_response.raw = io.BytesIO(b"1234567890"*12) self.get_mock.return_value = fixed_response # Start running the greenthreads. self.cf.start() self._g = self.cf._g def test_greenlets_running(self): """ Ensure that the two greenlets in the internal _g dictionary seem to be alive. :return: """ g = self.cf._g self.assertEquals(2, len(g)) for gl in g: started_and_not_failed = bool(gl) self.assertTrue(started_and_not_failed) def test_active_flow(self): """ Ensures that it seems to request frames and that it puts them on redis as expected. :return: """ # Should activate self.rdb.setex('wilsat:cams:archimedes:active', 10, 1) gevent.sleep(0.1) # Get current number of frames frames_first = self.cf._frames_this_cycle # Let it run gevent.sleep(0.1) # Ensure that the number of frames has increased frames_second = self.cf._frames_this_cycle self.assertGreater(frames_second, frames_first, "Number of rendered frames should increase steadily") # Ensure that mock (requests.get) has been called several times. self.assertGreater(self.get_mock.call_count, 5) # Ensure that the frames are being placed into redis. self.assertEquals(self.rdb.get('wilsat:cams:archimedes:lastframe'), b'1234567890'*12) def tearDown(self): for g in self._g: gevent.kill(g)
def run(): global greenthreads print("Starting Feeder component", flush=True) # Register exit handler signal.signal(signal.SIGINT, signal_handler) # print('Press Ctrl+C to exit.') # Load the cameras configuration data = yaml.load(open(config.CAMS_YML, 'r')) cams = data['cams'] # type: dict # print("Loaded {}".format(config.CAMS_YML)) while True: try: print("Running.") # Connect to the redis instance rdb = redis.StrictRedis(host=config.REDIS_HOST, port=config.REDIS_PORT, db=config.REDIS_DB, decode_responses=True) # Clear keys so that the stats are right. for key in rdb.scan_iter("{}:*".format(config.REDIS_PREFIX)): # print("Deleting: {}".format(key)) rdb.delete(key) # Create every cam feeder for cam_name, cam in cams.items(): # print('Adding cam {0} to the dict'.format(cam_name)) if 'rotation' in cam: rotation = float(cam['rotation']) else: rotation = 0.0 url = cam.get('img_url') mjpeg_url = cam.get('mjpeg_url') mpeg = cam.get('mpeg') h264 = cam.get('h264') h264_source = cam.get('h264_source') if mjpeg_url is not None: cf = MJPEGCamFeeder(rdb, config.REDIS_PREFIX, cam_name, mjpeg_url, 30, rotation) elif url is not None: cf = ImageRefreshCamFeeder(rdb, config.REDIS_PREFIX, cam_name, url, 30, rotation) elif h264_source is not None: cf = H264ToFramesFeeder(rdb, config.REDIS_PREFIX, cam_name, h264_source, config.FFMPEG_BIN) if mjpeg_url is None and url is None and h264_source is None: raise Exception( "img_url or mjpeg_url or h264_source is not specified for camera {}" .format(cam_name)) if mpeg is not None and mpeg is True: mpeg_cf = MPEGFeeder(rdb, cam_name, mjpeg_url, config.FFMPEG_BIN) cam_feeders[cam_name + '/mpeg'] = mpeg_cf mpeg_cf.start() if h264 is not None and h264 is True: h264_cf = H264Feeder(rdb, config.REDIS_PREFIX, cam_name, mjpeg_url, config.FFMPEG_BIN) cam_feeders[cam_name + '/h264'] = h264_cf h264_cf.start() cam_feeders[cam_name] = cf cf.start() # Create the watchdog g = gevent.spawn(watchdog, rdb) greenthreads.append(g) # Wait for all the greenlets cam_feeder_greenthreads_list = [ cam._g for cam in cam_feeders.values() ] for cam_feeder_greenthreads in cam_feeder_greenthreads_list: greenthreads.extend(cam_feeder_greenthreads) # Wait for greenlets for g in greenthreads: g.join() except Exception as ex: print("An exception was caught in the main function.") traceback.print_exc() print("Killing greenlets...") try: gevent.killall(greenthreads, block=True, timeout=30) except: traceback.print_exc() print("Could not kill greenlets. Exiting the feeders.") exit(1) greenthreads = [] print("Retrying in 5 seconds...") gevent.sleep(5) print("Retrying now.", flush=False)