def test_process_parser_analytics_count(self): """ Test that we correctly process parser with count metric """ os.environ['TERM'] = 'dumb' app = Logria(None, False, False) # Fake window size: 10 x 100 app.height = 10 app.width = 100 # Set fake previous render app.last_row = app.height - 3 # simulate the last row we can render to app.current_end = 80 # Simulate the last message rendered # Set fake messages app.messages = [str(x) for x in range(10)] app.parser_index = 0 app.last_index_processed = 0 app.analytics_enabled = True # Set parser, activate app.parser = Parser() app.parser.set_pattern( pattern=r'(\d)', type_='regex', name='Test', example='4', analytics_methods={ 'Item': 'count' } ) # Set analytics method manually app.parser._analytics_map = dict( zip(range(len(app.parser._analytics_methods.keys())), app.parser._analytics_methods.keys())) # Store previous message pointer app.previous_messages = app.messages # Process parser process_parser(app) self.assertEqual( app.messages, ['Item', ' 0: 1', ' 1: 1', ' 2: 1', ' 3: 1', ' 4: 1'])
def test_process_parser_invalid_index(self): """ Test that we correctly process parser with invalid index """ os.environ['TERM'] = 'dumb' app = Logria(None, False, False) # Fake window size: 10 x 100 app.height = 10 app.width = 100 # Set fake previous render app.last_row = app.height - 3 # simulate the last row we can render to app.current_end = 80 # Simulate the last message rendered # Set fake messages app.messages = [f'{x}+{x}+{x}' for x in range(10)] app.parser_index = 3 app.last_index_processed = 0 # Set parser, activate app.parser = Parser() app.parser.set_pattern( pattern='\+', type_='split', name='Test', example='a-a', analytics_methods={ 'Item 1': 'count', 'Item 2': 'count' } ) # Store previous message pointer app.previous_messages = app.messages # Process parser process_parser(app) self.assertEqual(app.messages, [])
def test_process_parser_no_analytics(self): """ Test that we correctly process parser with no analytics """ os.environ['TERM'] = 'dumb' app = Logria(None, False, False) # Fake window size: 10 x 100 app.height = 10 app.width = 100 # Set fake previous render app.last_row = app.height - 3 # simulate the last row we can render to app.current_end = 80 # Simulate the last message rendered # Set fake messages app.messages = [str(x) for x in range(10)] app.parser_index = 0 app.last_index_processed = 0 # Set parser, activate app.parser = Parser() app.parser.set_pattern( pattern=r'(\d)', type_='regex', name='Test', example='4', analytics_methods={ 'Item': 'average' } ) # Store previous message pointer app.previous_messages = app.messages # Process parser process_parser(app) self.assertEqual(app.messages, [str(x) for x in range(10)])
def main(self, stdscr) -> None: """ Main program loop, handles user control and logical flow """ curses.use_default_colors() self.stdscr = stdscr stdscr.keypad(1) height, width = stdscr.getmaxyx() # Get screen size # Save these values self.height = height self.width = width - 1 # Setup Output window output_start_row = 0 # Leave space for top border output_height = height - 3 # Leave space for command line self.last_row = output_height - output_start_row # The last row we can write to # Create the window with these sizes self.outwin = curses.newwin(output_height, width - 1, output_start_row, 0) self.outwin.refresh() # Setup Command line self.build_command_line() # Update the command line status reset_regex_status(self) # Disable cursor: curses.curs_set(0) # If the streams do not exist, create them if not self.streams: setup_streams(self) # Start the main app loop while True: # Update messages from the input stream's queues, track time t_0 = time.perf_counter() new_messages: int = 0 for stream in self.streams: while not stream.stderr.empty(): message = stream.stderr.get() self.stderr_messages.append(message) new_messages += 1 while not stream.stdout.empty(): message = stream.stdout.get() self.stdout_messages.append(message) new_messages += 1 # Prevent this loop from taking up 100% of the CPU dedicated to the main thread by delaying loops t_1 = time.perf_counter() - t_0 # Don't delay if the queue processing took too long time.sleep(max(0, self.poll_rate - t_1)) # Calculate new poll rate if self.smart_poll_rate: self.handle_smart_poll_rate(t_1, new_messages) # Since this is the first run, set the visible stream to the one that has the most messages if self.first_run and (len(self.stdout_messages) > 0 or len(self.stderr_messages) > 0): self.first_run = False # Default to stdout unless stderr has more messages if len(self.stdout_messages) >= len(self.stderr_messages): self.messages = self.stdout_messages else: self.messages = self.stderr_messages try: # Get keypress, raise curses.error if nothing detected keypress = self.command_line.getkey() resolve_keypress(self, keypress) except curses.error: if self.exit_val == -1: return # If we have an active filter/parser, process it/them if self.parser: # This may block if there are a lot of messages process_parser(self) if self.func_handle: # This may block if there are a lot of messages process_matches(self) # Always try to render self.render_text_in_output()