示例#1
0
def main():
    """
    Main app loop, handles parsing args and starting the app
    """
    if not os.isatty(0):
        # If we are getting piped to, use that input stream only
        raise ValueError('Piping is not supported!')
    else:
        # Args if we are passed -h
        parser = argparse.ArgumentParser(
            description=
            'A powerful CLI tool that puts log analytics at your fingertips.')
        parser.add_argument(
            '-e',
            action='append',
            type=str,
            help=
            'Command to pass through that will stream into this program, ex: logria -e \'tail -f log.txt\''
        )

        args = parser.parse_args()
        if args.e:
            args = args.e[0].split(' ')
            stream = CommandInputStream(args)
            stream.start()
        else:
            stream = None

    # Start the app
    app = Logria(
        stream)  # If the stream is None, the app will ask the user to init
    app.start()
示例#2
0
 def test_launch_no_stream(self):
     """
     Test that we can launch the app
     This should crash only due to a curses error
     """
     with self.assertRaises(error):
         os.environ['TERM'] = 'dumb'
         app = Logria(None, False)
         app.start()
示例#3
0
 def test_launch_with_file_stream(self):
     """
     Test that we can launch the app
     This should crash only due to a curses error
     """
     with self.assertRaises(error):
         os.environ['TERM'] = 'dumb'
         stream = FileInputStream(['readme.md'])
         app = Logria(stream, False)
         app.start()
示例#4
0
 def test_launch_with_command_stream(self):
     """
     Test that we can launch the app
     This should crash only due to a curses error
     """
     with self.assertRaises(error):
         os.environ['TERM'] = 'dumb'
         stream = CommandInputStream(['ls', '-l'])
         app = Logria(stream, False)
         app.start()
示例#5
0
def main():
    """
    Main app loop, handles parsing args and starting the app
    """
    # Setup CLI args
    parser = argparse.ArgumentParser(description=constants.APP_DESCRIPTION, )
    parser.add_argument('-v',
                        '--version',
                        action='version',
                        version=f'{APP_NAME} {VERSION}')
    parser.add_argument('-e',
                        action='append',
                        type=str,
                        help=constants.EXEC_HELP)
    parser.add_argument('-c',
                        '--no-cache',
                        dest='no_cache',
                        default=True,
                        action='store_false',
                        help=constants.HISTORY_HELP)
    parser.add_argument('-n',
                        '--no-smart-speed',
                        dest='no_smart_speed',
                        default=True,
                        action='store_false',
                        help=constants.SMART_SPEED_HELP)

    args = parser.parse_args()

    # pylint: disable=no-else-raise
    if not os.isatty(0):
        # If we are getting piped to, use that input stream only
        print(constants.PIPE_INPUT_ERROR)
        sys.exit(-1)
    else:
        if args.e:
            command = args.e[0].split(' ')
            stream = CommandInputStream(command)
            stream.start()
        else:
            # If the stream is None, the app will ask the user to init
            stream = None
        app = Logria(stream,
                     history_tape_cache=args.no_cache,
                     smart_poll_rate=args.no_smart_speed)

    app.start()
示例#6
0
    def test_process_matches(self):
        """
        Test that we correctly process matches
        """
        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(20)]

        # Set regex function, process
        app.func_handle = regex_generator.regex_test_generator(r'\d')
        process_matches(app)

        self.assertEqual(app.messages, [str(x) for x in range(20)])
    def test_render_first_items(self):
        """
        Test we render properly when stuck to the top
        """
        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(100)]

        # Set positional booleans
        app.manually_controlled_line = False
        app.stick_to_top = True
        app.stick_to_bottom = False

        start, end = determine_position(app, app.messages)
        self.assertEqual(start, -1)
        self.assertEqual(end, 6)
        app.stop()
    def test_render_scroll_pgup_keystroke(self):
        """
        Test we render properly when stuck to the bottom
        """
        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 = 40  # Simulate the last message rendered

        # Set fake messages
        app.messages = [str(x) for x in range(100)]

        # Set positional booleans
        app.manually_controlled_line = False
        app.stick_to_top = True
        app.stick_to_bottom = True

        # Scroll action
        resolve_keypress(app, 'KEY_PPAGE')

        start, end = determine_position(app, app.messages)
        self.assertEqual(start, 25)
        self.assertEqual(end, 33)
        app.stop()
    def test_can_render_matches(self):
        """
        Test we render properly when using matches
        """
        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}' for x in range(20)]

        # Set fake filter
        app.func_handle = regex_generator.regex_test_generator(r'\d\|\d')
        process_matches(app)

        # Set positional booleans
        app.manually_controlled_line = False
        app.stick_to_top = True
        app.stick_to_bottom = False

        start, end = determine_position(app, app.matched_rows)
        self.assertEqual(start, -1)
        self.assertEqual(end, 6)
        app.stop()
示例#10
0
    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, [])
示例#11
0
    def test_process_parser_analytics_average_no_numbers(self):
        """
        Test that we correctly process a parser with average metric but no source numbers
        """
        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 = [chr(x) for x in range(64, 80)]
        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': 'average'
            }
        )

        # Set analytics method manually
        app.parser._analytics_map = dict(
            zip(range(len(app.parser._analytics_methods.keys())), app.parser._analytics_methods.keys()))

        # Since we manually construct alaytics, create the the key
        app.parser.analytics[0] = None
        self.assertIsNone(app.parser.apply_analytics(0, 'A'))
示例#12
0
    def test_process_parser_split_no_pattern(self):
        """
        Test that we correctly process parser with split no pattern
        """
        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=None,
            type_='split',
            name='Test',
            example='4',
            analytics_methods={
                'Item': 'average'
            }
        )

        # Store previous message pointer
        app.previous_messages = app.messages

        # Process parser
        with self.assertRaises(ValueError):
            process_parser(app)
示例#13
0
    def test_process_parser_analytics_too_many_matches(self):
        """
        Test that we correctly process parser with too many matches
        """
        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, 20)]
        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)(\d)',
            type_='regex',
            name='Test',
            example='4',
            analytics_methods={
                'Item': 'invalid'
            }
        )

        # 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, [])