Skip to content

Commit

Permalink
Merge pull request #26 from soda480/0.2.4
Browse files Browse the repository at this point in the history
Update get_process_data to return tuple of process data and shared data
  • Loading branch information
soda480 authored Mar 2, 2021
2 parents 316d897 + c0f288c commit e5de13c
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 14 deletions.
2 changes: 1 addition & 1 deletion build.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
Author('Emilio Reyes', 'emilio.reyes@intel.com')]
summary = 'Mpcurses is an abstraction of the Python curses and multiprocessing libraries providing function execution and runtime visualization capabilities'
url = 'https://github.com/soda480/mpcurses'
version = '0.2.3'
version = '0.2.4'
default_task = [
'clean',
'analyze',
Expand Down
23 changes: 20 additions & 3 deletions examples/example5.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ def get_hex():
return uuid.uuid4().hex.upper()


def get_servers(bays=None):
def get_servers(**kwargs):
""" getting server data from enclosure
"""
logger.debug(kwargs)
bays = kwargs['bays']
servers = []
for bay in bays:
servers.append({
Expand All @@ -31,7 +33,8 @@ def get_servers(bays=None):
'servername': 'srv{}.company.com'.format(get_hex()[0:6]),
})
sleep(5)
return servers
kwargs['derived_key'] = 'derived_value'
return (servers, kwargs)

def get_servers2(**kwargs):
""" getting server data from enclosure if being passed as get_process_data value to MPcurses then should accept **kwargs as argument
Expand All @@ -45,7 +48,7 @@ def get_servers2(**kwargs):
'servername': 'srv{}.company.com'.format(get_hex()[0:6]),
})
sleep(5)
return servers
return (servers, kwargs)



Expand Down Expand Up @@ -111,9 +114,23 @@ def get_current_firmware():
return random.choice(['1.01', '2.01', '2.00', '2.02', '2.03', '2.04', '2.05', '2.06'])


def configure_logging():
""" configure logging
"""
rootLogger = logging.getLogger()
# must be set to this level so handlers can filter from this level
rootLogger.setLevel(logging.DEBUG)
file_handler = logging.FileHandler('example5.log')
file_formatter = logging.Formatter("%(asctime)s %(processName)s %(name)s [%(funcName)s] %(levelname)s %(message)s")
file_handler.setFormatter(file_formatter)
file_handler.setLevel(logging.DEBUG)
rootLogger.addHandler(file_handler)


def main():
""" main program
"""
configure_logging()
mpcurses = MPcurses(
function=update_firmware,
get_process_data=get_servers,
Expand Down
9 changes: 7 additions & 2 deletions src/main/python/mpcurses/mpcurses.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ def __init__(self, function, *, process_data=None, shared_data=None, processes_t
self.process_queue = SimpleQueue()

self.init_messages = [] if init_messages is None else init_messages
start_time = datetime.now().strftime('%m/%d/%Y %H:%M:%S')
self.init_messages.append(f'mpcurses: Started:{start_time}')

self.completed_processes = 0

Expand Down Expand Up @@ -188,7 +190,6 @@ def start_next_process(self):
'message_queue': self.message_queue,
'offset': offset,
'result_queue': self.result_queue})
# logger.debug(f'starting background process at offset {offset} with data {process_data}')
process.start()
logger.info(f'started background process at offset {offset} with process id {process.pid}')
# update active_processes dictionary with process meta-data for the process offset
Expand Down Expand Up @@ -250,10 +251,11 @@ def execute_get_process_data(self):
""" execute get_process_data function
"""
if self.get_process_data:
logger.debug(f'executing get process data method: {self.get_process_data.__name__}')
doc = self.get_process_data.__doc__
update_screen_status(self.screen, 'get-process-data', self.screen_layout['_screen'], data=doc)
kwargs = self.shared_data if self.shared_data else {}
self.process_data = self.get_process_data(**kwargs)
self.process_data, self.shared_data = self.get_process_data(**kwargs)
update_screen_status(self.screen, 'get-process-data', self.screen_layout['_screen'])
if not self.processes_to_start:
self.processes_to_start = len(self.process_data)
Expand All @@ -269,13 +271,16 @@ def setup_screen(self):
initialize_screen_offsets(self.screen, self.screen_layout, len(self.process_data), self.processes_to_start)

# update screen with all initialization messages if they were provided
logger.debug('updating screen with init messages')
for message in self.init_messages:
update_screen(message, self.screen, self.screen_layout)

# echo shared data to screen
logger.debug('echoing shared data to screen')
echo_to_screen(self.screen, self.shared_data, self.screen_layout)

# echo all process data to screen
logger.debug('echoing process data to screen')
for offset, data in enumerate(self.process_data):
echo_to_screen(self.screen, data, self.screen_layout, offset=offset)

Expand Down
20 changes: 12 additions & 8 deletions src/unittest/python/test_mpcurses.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ def tearDown(self):
"""
pass

def test__init_Should_SetDefaults_When_Called(self, *patches):
@patch('mpcurses.mpcurses.datetime')
def test__init_Should_SetDefaults_When_Called(self, datetime_patch, *patches):
datetime_patch.now.return_value.strftime.return_value = 'current-time'
client = MPcurses(function=Mock(__name__='mockfunc'))
self.assertEqual(client.process_data, [{}])
self.assertEqual(client.shared_data, {})
self.assertEqual(client.processes_to_start, 1)
self.assertEqual(client.init_messages, [])
self.assertEqual(client.init_messages, ['mpcurses: Started:current-time'])

@patch('mpcurses.mpcurses.queue_handler')
def test__init_Should_SetDefaults_When_FunctionNotWrapped(self, queue_handler_patch, *patches):
Expand Down Expand Up @@ -254,31 +256,33 @@ def test__execute_get_process_data_Should_CallExpected_When_NoGetProcessData(sel
@patch('mpcurses.mpcurses.update_screen_status')
def test__execute_get_process_data_Should_CallExpected_When_GetProcessData(self, update_screen_status_patch, *patches):
function_mock = Mock(__name__='mockfunc')
get_process_data_mock = Mock(__doc__='getting data')
get_process_data_mock.return_value = [{'data': 1}, {'data': 2}]
get_process_data_mock = Mock(__name__='get_my_process_data', __doc__='getting data')
get_process_data_mock.return_value = ([{'data': 1}, {'data': 2}], {'key1', 'value1'})
client = MPcurses(function=function_mock, get_process_data=get_process_data_mock, screen_layout={'_screen': {}})
client.execute_get_process_data()
client.screen = None
call1 = call(client.screen, 'get-process-data', {}, data='getting data')
self.assertTrue(call1 in update_screen_status_patch.mock_calls)
get_process_data_mock.assert_called_once_with()
self.assertEqual(client.process_data, get_process_data_mock.return_value)
self.assertEqual(client.process_data, get_process_data_mock.return_value[0])
self.assertEqual(client.shared_data, get_process_data_mock.return_value[1])
call2 = call(client.screen, 'get-process-data', {})
self.assertTrue(call2 in update_screen_status_patch.mock_calls)
self.assertEqual(client.processes_to_start, 2)

@patch('mpcurses.mpcurses.update_screen_status')
def test__execute_get_process_data_Should_CallExpected_When_GetProcessDataStartProcesses(self, update_screen_status_patch, *patches):
function_mock = Mock(__name__='mockfunc')
get_process_data_mock = Mock(__doc__='getting data')
get_process_data_mock.return_value = [{'data': 1}, {'data': 2}]
get_process_data_mock = Mock(__name__='get_my_process_data', __doc__='getting data')
get_process_data_mock.return_value = ([{'data': 1}, {'data': 2}], {'arg1': 'value1', 'arg2': 'value2', 'arg3': 'value3'})
client = MPcurses(function=function_mock, get_process_data=get_process_data_mock, screen_layout={'_screen': {}}, processes_to_start=1, shared_data={'arg1': 'value1', 'arg2': 'value2'})
client.execute_get_process_data()
client.screen = None
call1 = call(client.screen, 'get-process-data', {}, data='getting data')
self.assertTrue(call1 in update_screen_status_patch.mock_calls)
get_process_data_mock.assert_called_once_with(arg1='value1', arg2='value2')
self.assertEqual(client.process_data, get_process_data_mock.return_value)
self.assertEqual(client.process_data, get_process_data_mock.return_value[0])
self.assertEqual(client.shared_data, get_process_data_mock.return_value[1])
call2 = call(client.screen, 'get-process-data', {})
self.assertTrue(call2 in update_screen_status_patch.mock_calls)
self.assertEqual(client.processes_to_start, 1)
Expand Down

0 comments on commit e5de13c

Please sign in to comment.