def test_receive_get_log_success(self): program_status = ProgramStatusFactory(running=True) program = program_status.program error_status = Status.ok({ 'method': 'get_log', 'result': { 'log': 'this is the content of a logfile', 'uuid': program_status.command_uuid, }, }) # connect webinterface webinterface = WSClient() webinterface.join_group('notifications') ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': error_status.to_json()}, ) # test if the webinterface gets the error message self.assertEqual( Status.ok({ 'log': 'this is the content of a logfile', 'pid': str(program.id), }), Status.from_json(json.dumps(webinterface.receive())), )
def test_receive_online_success(self): slave = SlaveOnlineFactory(online=False) expected_status = Status.ok({'method': 'online'}) expected_status.uuid = slave.command_uuid # connect webinterface on /notifications webinterface = WSClient() webinterface.join_group('notifications') # send online answer ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': expected_status.to_json()}, ) self.assertTrue(SlaveModel.objects.get(id=slave.id).is_online) # test if a connected message was send on /notifications self.assertEqual( Status.ok({ 'slave_status': 'connected', 'sid': str(slave.id), }), Status.from_json(json.dumps(webinterface.receive())), )
def test_receive_filesystem_restore_success(self): filesystem = MovedFileFactory() error_status = Status.ok({ 'method': 'filesystem_restore', 'result': None, }) error_status.uuid = filesystem.command_uuid # connect webinterface webinterface = WSClient() webinterface.join_group('notifications') ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': error_status.to_json()}, ) query = FilesystemModel.objects.get(id=filesystem.id) self.assertEqual(query.hash_value, "") self.assertEqual(query.error_code, "") self.assertEqual( Status.ok({ 'filesystem_status': 'restored', 'fid': str(filesystem.id), }), Status.from_json(json.dumps(webinterface.receive())), )
def test_receive_execute_success(self): program_status = ProgramStatusFactory(running=True) program = program_status.program expected_status = Status.ok({'method': 'execute', 'result': 0}) expected_status.uuid = program_status.command_uuid # connect webinterface webinterface = WSClient() webinterface.send_and_consume( 'websocket.connect', path='/notifications', ) ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': expected_status.to_json()}, ) query = ProgramStatusModel.objects.filter(program=program, code=0) self.assertTrue(query.count() == 1) self.assertFalse(query.first().running) # test if the webinterface gets the "finished" message self.assertEqual( Status.ok({ 'program_status': 'finished', 'pid': str(program.id), 'code': 0, }), Status.from_json(json.dumps(webinterface.receive())), )
def test_receive_chain_commands_success(self): filesystem = FileFactory() moved = MovedFileFactory.build() error_status1 = Status.ok({ 'method': 'filesystem_move', 'result': moved.hash_value, }) error_status1.uuid = filesystem.command_uuid error_status2 = Status.ok({ 'method': 'filesystem_move', 'result': moved.hash_value, }) error_status2.uuid = filesystem.command_uuid error_chain = Status.ok({ 'method': 'chain_execution', 'result': [dict(error_status1), dict(error_status2)], }) # connect webinterface webinterface = WSClient() webinterface.join_group('notifications') ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': error_chain.to_json()}, ) query = FilesystemModel.objects.get(id=filesystem.id) self.assertEqual(query.hash_value, moved.hash_value) self.assertEqual(query.error_code, "") self.assertEqual( Status.ok({ 'filesystem_status': 'moved', 'fid': str(filesystem.id), }), Status.from_json(json.dumps(webinterface.receive())), ) self.assertEqual( Status.ok({ 'filesystem_status': 'moved', 'fid': str(filesystem.id), }), Status.from_json(json.dumps(webinterface.receive())), ) self.assertIsNone(webinterface.receive())
def test_receive_execute_slave_not_exists(self): program_status = ProgramStatusFactory(running=True) program = program_status.program expected_status = Status.ok({'method': 'execute', 'result': 0}) expected_status.uuid = program_status.command_uuid # connect webinterface webinterface = WSClient() webinterface.send_and_consume( 'websocket.connect', path='/notifications', ) program.delete() ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': expected_status.to_json()}, ) self.assertFalse( ProgramStatusModel.objects.filter(program=program).exists()) # test if the webinterface gets the "finished" message self.assertIsNone(webinterface.receive())
def test_rpc_method_cancel_method(self): # pylint: disable=R0201 """ Tests what happens if you cancel a running method """ @Rpc.method @asyncio.coroutine def sleep(sec): # pylint: disable=R0201,W0612 """ Simple async rpc function, that raises an Exception. """ try: yield from asyncio.sleep(sec) except asyncio.CancelledError: return -15 sleep_cmd = Command(method='sleep', sec=1) cancel_cmd = Command(method='sleep') cancel_cmd.uuid = sleep_cmd.uuid status = Status.ok({'method': 'sleep', 'result': -15}) status.uuid = sleep_cmd.uuid Server( [ sleep_cmd.to_json(), cancel_cmd.to_json(), ], [ status.to_json(), ], ).run()
def test_receive_execute_with_error_status(self): program_status = ProgramStatusFactory(running=True) program = program_status.program error_status = Status.err({ 'method': 'execute', 'result': str(Exception('foobar')), }) error_status.uuid = program_status.command_uuid # connect webinterface webinterface = WSClient() webinterface.join_group('notifications') ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': error_status.to_json()}, ) query = ProgramStatusModel.objects.get(program=program) self.assertFalse(query.running) self.assertEqual(query.code, 'foobar') # test if the webinterface gets the error message self.assertEqual( Status.ok({ 'program_status': 'finished', 'pid': str(program.id), 'code': 'foobar', }), Status.from_json(json.dumps(webinterface.receive())), )
def test_math_add(self): # pylint: disable=R0201 """ Testing simple math add function with async features. """ @Rpc.method def math_add(integer1, integer2): # pylint: disable=R0201,W0612 """ Simple add function with async. Arguments --------- integer1: first operand integer2: second operand """ res = (integer1 + integer2) return res cmd = Command("math_add", integer1=1, integer2=2) status = Status.ok({'method': 'math_add', 'result': 3}) status.uuid = cmd.uuid Server( [ cmd.to_json(), ], [ status.to_json(), ], ).run()
def filesystem_restore(request, filesystem_id): """ Processes an method invocation (restore) for an `FilesystemModel`. (see @frontend.controller.filesystem_restore) HTTP Methods ------------ POST: Invokes the method for the `FilesystemModel` (which is specified in the URL). Parameters ---------- request: HttpRequest The request which should be processed. Returns ------- HttpResponse: If the HTTP method is not supported, then an `HttpResponseForbidden` is returned. """ if request.method == 'POST': try: filesystem = FilesystemModel.objects.get(id=filesystem_id) try: fs_restore(filesystem) return StatusResponse(Status.ok("")) except FsimError as err: return StatusResponse(err) except FilesystemModel.DoesNotExist as err: return StatusResponse(FilesystemNotExistError(err, filesystem_id)) else: return HttpResponseForbidden()
def test_receive_get_log_program_not_exists(self): error_status = Status.ok({ 'method': 'get_log', 'result': { 'log': '', 'uuid': '0' }, }) # connect webinterface webinterface = WSClient() webinterface.join_group('notifications') ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': error_status.to_json()}, ) # test if the webinterface gets the error message self.assertEqual( Status.err('Received log from unknown program!'), Status.from_json(json.dumps(webinterface.receive())), )
def test_state_init(self): webinterface = WSClient() webinterface.join_group('notifications') ScriptModel.objects.filter(id=self.script.id).update( is_running=True, is_initialized=True, current_index=-1, ) self.sched._Scheduler__index = -1 self.sched._Scheduler__script = self.script.id self.sched._Scheduler__event = asyncio.Event(loop=self.sched.loop) self.sched._Scheduler__state = SchedulerStatus.INIT self.sched._Scheduler__state_init() self.assertEqual( self.sched._Scheduler__state, SchedulerStatus.WAITING_FOR_SLAVES, ) msg1 = Status.from_json(json.dumps(webinterface.receive())) msg2 = Status.from_json(json.dumps(webinterface.receive())) msg3 = Status.from_json(json.dumps(webinterface.receive())) expct1 = Status.ok({ 'script_status': 'waiting_for_slaves', 'script_id': self.script.id, }) expct2 = Status.ok({ 'message': "Send start command to client `{}`".format(self.prog1.slave.name), }) expct3 = Status.ok({ 'message': "Send start command to client `{}`".format(self.prog2.slave.name), }) self.assertStatusSet( [msg1, msg2, msg3], [expct1, expct2, expct3], )
def test_receive_unknown_message_type(self): ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': Status.ok({ 'method': '' }).to_json()}, ) self.assertIsNone(ws_client.receive())
def notify(message): """ Sending the given `message` to the notification channel, inidcating that the message is not an error. Parameters ---------- message: JSON object This message is send to the web interface with an Status.ok() wrapped around. """ Group('notifications').send({'text': Status.ok(message).to_json()})
def test_connect_and_disconnect_success(self): ws_client = WSClient() ws_client.send_and_consume( 'websocket.connect', path='/notifications', ) # test if ws_client is part of 'notifications' Group('notifications').send({'text': Status.ok('').to_json()}) self.assertEqual( Status.ok(''), Status.from_json(json.dumps(ws_client.receive())), ) ws_client.send_and_consume( 'websocket.disconnect', path='/notifications', ) # test if ws_client was removed from 'notifications' Group('notifications').send({'text': Status.ok('').to_json()}) self.assertIsNone(ws_client.receive())
def enable_remote(self): """ Enables remote logging to the websocket located on 'self.__url'. First the existing log gets send, then updates follow on every request (an empty message)by the receiver. """ with self.__lock: self.__ws_connection = yield from websockets.connect(self.__url) log = self.__log_file.read() msg = {'log': log.decode(), 'pid': self.__pid_on_master} yield from self.__ws_connection.send(Status.ok(msg).to_json()) yield from self.__ws_connection.recv() while True: yield from self.__ws_buffer_has_content.wait() with self.__lock: msg = { 'log': self.__ws_buffer.decode(), 'pid': self.__pid_on_master } self.__ws_buffer = b'' self.__ws_buffer_has_content.clear() try: yield from self.__ws_connection.send(Status.ok(msg).to_json()) yield from self.__ws_connection.recv() except websockets.exceptions.ConnectionClosed: break if msg['log'] == b''.decode(): break # if the stream from tee has finished the buffer gets send and # cleared in the next iterations which terminates the loop if self.__ws_finished: self.__ws_buffer_has_content.set()
def ok(cls, payload, **kwargs): """ Shorthand for StatusResponse(Status.ok(payload)) Arguments --------- payload: Payload for Status object **kwargs: arguments for HttpResponse Returns ------- StatusResponse object with 'ok' in Status """ return cls(Status.ok(payload), **kwargs)
def test_receive_filesystem_restore_filesystem_not_exists(self): webinterface = WSClient() webinterface.join_group('notifications') error_status = Status.ok({ 'method': 'filesystem_restore', 'result': None, }) ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': error_status.to_json()}, ) self.assertIsNone(webinterface.receive())
def test_disconnect_success(self): slave = SlaveOnlineFactory() program_status = ProgramStatusFactory(program__slave=slave) program = program_status.program # connect client on /commands ws_client = WSClient() ws_client.send_and_consume( 'websocket.connect', path='/commands', content={'client': [slave.ip_address, slave.mac_address]}) # connect webinterface on /notifications webinterface = WSClient() webinterface.send_and_consume( 'websocket.connect', path='/notifications', ) # throw away connect repsonse ws_client.receive() ws_client.send_and_consume('websocket.disconnect', path='/commands') # test if SlaveStatus was to offline self.assertFalse(SlaveModel.objects.get(id=slave.id).is_online) Group('client_{}'.format(slave.id)).send( {'text': 'ok'}, immediately=True, ) self.assertIsNone(ws_client.receive()) # test if program status was removed self.assertFalse( ProgramStatusModel.objects.filter(program=program).exists()) # test if a "disconnected" message has been send to the webinterface self.assertEqual( Status.ok({ 'slave_status': 'disconnected', 'sid': str(slave.id) }), Status.from_json(json.dumps(webinterface.receive())))
def test_state_success(self): webinterface = WSClient() webinterface.join_group('notifications') self.sched._Scheduler__event = asyncio.Event(loop=self.sched.loop) self.sched._Scheduler__script = self.script.id self.sched._Scheduler__state = SchedulerStatus.SUCCESS self.sched._Scheduler__state_success() self.assertEqual( self.sched._Scheduler__state, SchedulerStatus.SUCCESS, ) self.assertEqual( Status.ok({ 'script_status': 'success', 'script_id': self.script.id, }), Status.from_json(json.dumps(webinterface.receive())), )
def test_state_next_offline_program(self): webinterface = WSClient() webinterface.join_group('notifications') self.slave1.online = True self.slave1.save() self.sched._Scheduler__index = -1 self.sched._Scheduler__event = asyncio.Event(loop=self.sched.loop) self.sched._Scheduler__script = self.script.id self.sched._Scheduler__state = SchedulerStatus.NEXT_STEP self.sched._Scheduler__state_next() self.assertEqual( Status.ok({ 'program_status': 'started', 'pid': self.prog1.id, }), Status.from_json(json.dumps(webinterface.receive())), ) self.assertEqual( self.sched._Scheduler__state, SchedulerStatus.WAITING_FOR_PROGRAMS_FILESYSTEMS, ) self.sched._Scheduler__state = SchedulerStatus.NEXT_STEP self.sched._Scheduler__state_next() self.assertEqual( self.sched._Scheduler__state, SchedulerStatus.ERROR, ) self.assertStatusRegex( Status.err(SlaveOfflineError), Status.err(self.sched._Scheduler__error_code), )
def test_connect_and_disconnect_success(self): webinterface = WSClient() webinterface.join_group('notifications') ws_client = WSClient() ws_client.send_and_consume('websocket.connect', path='/logs') self.assertIsNone(ws_client.receive()) msg = Status.ok({ 'log': ''.join([ choice(string.ascii_letters + string.digits) for _ in range(500) ]), 'pid': choice(string.digits) }) ws_client.send_and_consume('websocket.receive', path='/logs', content={'text': msg.to_json()}) self.assertEqual(msg, Status.from_json(json.dumps(webinterface.receive())))
def test_state_error(self): webinterface = WSClient() webinterface.join_group('notifications') self.sched._Scheduler__event = asyncio.Event(loop=self.sched.loop) self.sched._Scheduler__script = self.script.id self.sched._Scheduler__error_code = "Wow an error occurred." self.sched._Scheduler__state = SchedulerStatus.ERROR self.sched._Scheduler__state_error() self.assertEqual( self.sched._Scheduler__state, SchedulerStatus.ERROR, ) self.assertEqual( Status.ok({ 'script_status': 'error', 'error_code': 'Wow an error occurred.', 'script_id': self.script.id, }), Status.from_json(json.dumps(webinterface.receive())), )
def test_error_close(self): # pylint: disable=R0201 """ Tests if RPC-Receiver doesn't raise an exception if closed during execution. """ @Rpc.method @asyncio.coroutine def async_sleep(): # pylint: disable=R0201,W0612 """ Simple function that sleeps. """ yield from asyncio.sleep(10) cmd = Command("async_sleep", integer1=1, integer2=2) status = Status.ok({'method': 'async_sleep', 'result': ''}) status.uuid = cmd.uuid CloseFailServer( [ cmd.to_json(), ], [ status.to_json(), ], ).run()
def test_receive_online_slave_not_exists(self): slave = SlaveOnlineFactory(online=False) expected_status = Status.ok({'method': 'online'}) expected_status.uuid = slave.command_uuid # connect webinterface on /notifications webinterface = WSClient() webinterface.join_group('notifications') slave.delete() # send online answer ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': expected_status.to_json()}, ) self.assertFalse(SlaveModel.objects.filter(id=slave.id).exists()) # test if a connected message was send on /notifications self.assertIsNone(webinterface.receive())
def test_state_next_finished(self): webinterface = WSClient() webinterface.join_group('notifications') self.slave1.online = True self.slave1.save() self.slave2.online = True self.slave2.save() ProgramStatusModel.objects.create(program=self.prog1, code='0', command_uuid='0', start_time=now()) self.sched._Scheduler__index = -1 self.sched._Scheduler__event = asyncio.Event(loop=self.sched.loop) self.sched._Scheduler__script = self.script.id self.sched._Scheduler__state = SchedulerStatus.NEXT_STEP self.sched._Scheduler__state_next() self.assertEqual( self.sched._Scheduler__state, SchedulerStatus.WAITING_FOR_PROGRAMS_FILESYSTEMS, ) if self.prog1.start_time > 0: start_time = self.prog1.start_time else: start_time = 0 msg1 = Status.from_json(json.dumps(webinterface.receive())) expct1 = Status.ok({ 'script_status': 'next_step', 'index': 0, 'last_index': -1, 'start_time': start_time, 'script_id': self.script.id, }) self.assertStatusSet([msg1], [expct1]) ProgramStatusModel.objects.create(program=self.prog2, code='0', command_uuid='1', start_time=now()) self.sched._Scheduler__state = SchedulerStatus.NEXT_STEP self.sched._Scheduler__state_next() self.assertEqual( self.sched._Scheduler__state, SchedulerStatus.WAITING_FOR_PROGRAMS_FILESYSTEMS, ) if self.prog2.start_time > 0: start_time = self.prog2.start_time else: start_time = 0 msg1 = Status.from_json(json.dumps(webinterface.receive())) expct1 = Status.ok({ 'script_status': 'next_step', 'index': 2, 'last_index': 0, 'start_time': start_time, 'script_id': self.script.id, }) self.assertStatusSet([msg1], [expct1]) self.sched._Scheduler__state = SchedulerStatus.NEXT_STEP self.sched._Scheduler__state_next() self.assertEqual( self.sched._Scheduler__state, SchedulerStatus.SUCCESS, ) self.assertEqual( Status.ok({ 'script_status': 'next_step', 'index': -1, 'last_index': 2, 'start_time': 0, 'script_id': self.script.id, }), Status.from_json(json.dumps(webinterface.receive())), )
def test_state_next(self): webinterface = WSClient() webinterface.join_group('notifications') self.slave1.online = True self.slave1.save() self.slave2.online = True self.slave2.save() self.sched._Scheduler__index = -1 self.sched._Scheduler__event = asyncio.Event(loop=self.sched.loop) self.sched._Scheduler__script = self.script.id self.sched._Scheduler__state = SchedulerStatus.NEXT_STEP self.sched._Scheduler__state_next() self.assertEqual( self.sched._Scheduler__state, SchedulerStatus.WAITING_FOR_PROGRAMS_FILESYSTEMS, ) if self.prog1.start_time > 0: start_time = self.prog1.start_time else: start_time = 0 msg1 = Status.from_json(json.dumps(webinterface.receive())) msg2 = Status.from_json(json.dumps(webinterface.receive())) expct1 = Status.ok({ 'script_status': 'next_step', 'index': 0, 'last_index': -1, 'start_time': start_time, 'script_id': self.script.id, }) expct2 = Status.ok({ 'program_status': 'started', 'pid': self.prog1.id, }) self.assertStatusSet([msg1, msg2], [expct1, expct2]) self.sched._Scheduler__state = SchedulerStatus.NEXT_STEP self.sched._Scheduler__state_next() self.assertEqual( self.sched._Scheduler__state, SchedulerStatus.WAITING_FOR_PROGRAMS_FILESYSTEMS, ) if self.prog2.start_time > 0: start_time = self.prog2.start_time else: start_time = 0 msg1 = Status.from_json(json.dumps(webinterface.receive())) msg2 = Status.from_json(json.dumps(webinterface.receive())) expct1 = Status.ok({ 'script_status': 'next_step', 'index': 2, 'last_index': 0, 'start_time': start_time, 'script_id': self.script.id, }) expct2 = Status.ok({ 'program_status': 'started', 'pid': self.prog2.id, }) self.assertStatusSet([msg1, msg2], [expct1, expct2]) self.sched._Scheduler__state = SchedulerStatus.NEXT_STEP self.sched._Scheduler__state_next() self.assertEqual( self.sched._Scheduler__state, SchedulerStatus.SUCCESS, ) self.assertEqual( Status.ok({ 'script_status': 'next_step', 'index': -1, 'last_index': 2, 'start_time': 0, 'script_id': self.script.id, }), Status.from_json(json.dumps(webinterface.receive())), )