コード例 #1
0
    def _TestScanSourceVssImage(self, test_file):
        """Tests the ScanSource function on the VSS test image.

    Args:
      test_file: the path of the test file.
    """
        test_front_end = extraction_frontend.ExtractionFrontend(
            self._input_reader, self._output_writer)

        options = frontend.Options()
        options.source = test_file
        options.vss_stores = '1,2'

        test_front_end.ParseOptions(options)

        test_front_end.ScanSource(options)
        path_spec = test_front_end.GetSourcePathSpec()
        self.assertNotEqual(path_spec, None)
        self.assertEqual(path_spec.type_indicator,
                         dfvfs_definitions.TYPE_INDICATOR_TSK)
        # pylint: disable=protected-access
        self.assertEqual(test_front_end._partition_offset, 0)
        self.assertEqual(test_front_end._vss_stores, [1, 2])

        options = frontend.Options()
        options.source = test_file
        options.vss_stores = '1'

        test_front_end.ParseOptions(options)

        test_front_end.ScanSource(options)
        path_spec = test_front_end.GetSourcePathSpec()
        self.assertNotEqual(path_spec, None)
        self.assertEqual(path_spec.type_indicator,
                         dfvfs_definitions.TYPE_INDICATOR_TSK)
        # pylint: disable=protected-access
        self.assertEqual(test_front_end._partition_offset, 0)
        self.assertEqual(test_front_end._vss_stores, [1])

        options = frontend.Options()
        options.source = test_file
        options.vss_stores = 'all'

        test_front_end.ParseOptions(options)

        test_front_end.ScanSource(options)
        path_spec = test_front_end.GetSourcePathSpec()
        self.assertNotEqual(path_spec, None)
        self.assertEqual(path_spec.type_indicator,
                         dfvfs_definitions.TYPE_INDICATOR_TSK)
        # pylint: disable=protected-access
        self.assertEqual(test_front_end._partition_offset, 0)
        self.assertEqual(test_front_end._vss_stores, [1, 2])
コード例 #2
0
    def _TestScanSourcePartitionedImage(self, test_file):
        """Tests the ScanSource function on the partitioned test image.

    Args:
      test_file: the path of the test file.
    """
        test_front_end = extraction_frontend.ExtractionFrontend(
            self._input_reader, self._output_writer)

        options = frontend.Options()
        options.source = test_file
        options.image_offset_bytes = 0x0002c000

        test_front_end.ParseOptions(options)

        test_front_end.ScanSource(options)
        path_spec = test_front_end.GetSourcePathSpec()
        self.assertNotEqual(path_spec, None)
        self.assertEqual(path_spec.type_indicator,
                         dfvfs_definitions.TYPE_INDICATOR_TSK)
        # pylint: disable=protected-access
        self.assertEqual(test_front_end._partition_offset, 180224)

        options = frontend.Options()
        options.source = test_file
        options.image_offset = 352
        options.bytes_per_sector = 512

        test_front_end.ParseOptions(options)

        test_front_end.ScanSource(options)
        path_spec = test_front_end.GetSourcePathSpec()
        self.assertNotEqual(path_spec, None)
        self.assertEqual(path_spec.type_indicator,
                         dfvfs_definitions.TYPE_INDICATOR_TSK)
        # pylint: disable=protected-access
        self.assertEqual(test_front_end._partition_offset, 180224)

        options = frontend.Options()
        options.source = test_file
        options.partition_number = 2

        test_front_end.ParseOptions(options)

        test_front_end.ScanSource(options)
        path_spec = test_front_end.GetSourcePathSpec()
        self.assertNotEqual(path_spec, None)
        self.assertEqual(path_spec.type_indicator,
                         dfvfs_definitions.TYPE_INDICATOR_TSK)
        # pylint: disable=protected-access
        self.assertEqual(test_front_end._partition_offset, 180224)
コード例 #3
0
ファイル: image_export_test.py プロジェクト: f-s-p/plaso
    def testProcessSourceExtractWithFilter(self):
        """Tests extract with a filter file."""
        test_front_end = image_export.ImageExportFrontend()

        options = frontend.Options()
        options.image = self._GetTestFilePath([u'image.qcow2'])
        options.path = self._temp_directory

        options.filter = os.path.join(self._temp_directory, u'filter.txt')
        with open(options.filter, 'wb') as file_object:
            file_object.write(b'/a_directory/.+_file\n')

        test_front_end.ParseOptions(options, source_option=u'image')

        test_front_end.ProcessSource(options)

        expected_extracted_files = sorted([
            os.path.join(self._temp_directory, u'filter.txt'),
            os.path.join(self._temp_directory, u'a_directory'),
            os.path.join(self._temp_directory, u'a_directory',
                         u'another_file'),
            os.path.join(self._temp_directory, u'a_directory', u'a_file')
        ])

        extracted_files = self._RecursiveList(self._temp_directory)

        self.assertEqual(sorted(extracted_files), expected_extracted_files)
コード例 #4
0
ファイル: image_export_test.py プロジェクト: f-s-p/plaso
    def testProcessSourceExtractWithDateTimeFilter(self):
        """Tests extract with a date time filter."""
        test_front_end = image_export.ImageExportFrontend()

        options = frontend.Options()
        options.image = self._GetTestFilePath([u'image.qcow2'])
        options.path = self._temp_directory
        options.include_duplicates = True
        options.date_filters = [
            u'ctime, 2012-05-25 15:59:00, 2012-05-25 15:59:20'
        ]

        test_front_end.ParseOptions(options, source_option=u'image')
        test_front_end.PrintFilterCollection()

        test_front_end.ProcessSource(options)

        expected_extracted_files = sorted([
            os.path.join(self._temp_directory, u'a_directory'),
            os.path.join(self._temp_directory, u'a_directory', u'a_file')
        ])

        extracted_files = self._RecursiveList(self._temp_directory)

        self.assertEqual(sorted(extracted_files), expected_extracted_files)
コード例 #5
0
ファイル: pinfo_test.py プロジェクト: f-s-p/plaso
    def testGetStorageInformation(self):
        """Tests the get storage information function."""
        test_front_end = pinfo.PinfoFrontend()

        options = frontend.Options()
        options.storage_file = os.path.join(self._TEST_DATA_PATH,
                                            'psort_test.out')

        test_front_end.ParseOptions(options)

        storage_information_list = list(test_front_end.GetStorageInformation())

        self.assertEqual(len(storage_information_list), 1)

        lines_of_text = storage_information_list[0].split(u'\n')

        expected_line_of_text = u'-' * 80
        self.assertEqual(lines_of_text[0], expected_line_of_text)
        self.assertEqual(lines_of_text[2], expected_line_of_text)

        self.assertEqual(lines_of_text[1], u'\t\tPlaso Storage Information')

        expected_line_of_text = u'Storage file:\t\t{0:s}'.format(
            options.storage_file)
        self.assertEqual(lines_of_text[3], expected_line_of_text)

        self.assertEqual(lines_of_text[4], u'Source processed:\tsyslog')

        expected_line_of_text = u'Time of processing:\t2014-02-15T04:33:16+00:00'
        self.assertEqual(lines_of_text[5], expected_line_of_text)

        self.assertEqual(lines_of_text[6], u'')
        self.assertEqual(lines_of_text[7], u'Collection information:')
コード例 #6
0
ファイル: log2timeline_test.py プロジェクト: f-s-p/plaso
    def testGetStorageInformation(self):
        """Tests the get storage information function."""
        test_front_end = log2timeline.Log2TimelineFrontend()

        options = frontend.Options()
        options.source = self._GetTestFilePath([u'ímynd.dd'])

        storage_file_path = os.path.join(self._temp_directory, u'plaso.db')

        test_front_end.ParseOptions(options)
        test_front_end.SetStorageFile(storage_file_path=storage_file_path)
        test_front_end.SetRunForeman(run_foreman=False)

        test_front_end.ProcessSource(options)

        try:
            storage_file = storage.StorageFile(storage_file_path,
                                               read_only=True)
        except IOError:
            # This is not a storage file, we should fail.
            self.assertTrue(False)

        # Make sure we can read an event out of the storage.
        event_object = storage_file.GetSortedEntry()
        self.assertIsNotNone(event_object)
コード例 #7
0
ファイル: preg_test.py プロジェクト: cnbird1999/plaso
    def _GetHelperAndOutputWriter(self):
        """Return a helper object (instance of PregHelper) and an output writer."""
        hive_storage = preg.PregStorage()
        options = frontend.Options()

        output_writer = test_lib.StringIOOutputWriter()
        test_front_end = preg.PregFrontend(output_writer)

        shell_helper = preg.PregHelper(options, test_front_end, hive_storage)

        return shell_helper, output_writer
コード例 #8
0
    def testParseOptions(self):
        """Tests the parse options function."""
        test_front_end = extraction_frontend.ExtractionFrontend(
            self._input_reader, self._output_writer)

        options = frontend.Options()

        with self.assertRaises(errors.BadConfigOption):
            test_front_end.ParseOptions(options)

        options.source = self._GetTestFilePath([u'ímynd.dd'])

        test_front_end.ParseOptions(options)
コード例 #9
0
ファイル: preg_test.py プロジェクト: cnbird1999/plaso
    def testBadRun(self):
        """Test few functions that should raise exceptions."""
        shell_helper, _ = self._GetHelperAndOutputWriter()

        options = frontend.Options()
        options.foo = u'bar'

        with self.assertRaises(errors.BadConfigOption):
            shell_helper.tool_front_end.ParseOptions(options)

        options.regfile = 'this_path_does_not_exist'
        with self.assertRaises(errors.BadConfigOption):
            shell_helper.tool_front_end.ParseOptions(options)
コード例 #10
0
    def testOpenStorageFile(self):
        """Tests the open storage file function."""
        test_front_end = analysis_frontend.AnalysisFrontend(
            self._input_reader, self._output_writer)

        options = frontend.Options()
        options.storage_file = self._GetTestFilePath([u'psort_test.out'])

        test_front_end.ParseOptions(options)
        storage_file = test_front_end.OpenStorageFile()

        self.assertIsInstance(storage_file, storage.StorageFile)

        storage_file.Close()
コード例 #11
0
    def testParseOptions(self):
        """Tests the parse options function."""
        test_front_end = analysis_frontend.AnalysisFrontend(
            self._input_reader, self._output_writer)

        options = frontend.Options()

        with self.assertRaises(errors.BadConfigOption):
            test_front_end.ParseOptions(options)

        options.storage_file = self._GetTestFilePath([u'no_such_file.out'])

        with self.assertRaises(errors.BadConfigOption):
            test_front_end.ParseOptions(options)

        options.storage_file = self._GetTestFilePath([u'psort_test.out'])

        test_front_end.ParseOptions(options)
コード例 #12
0
ファイル: image_export_test.py プロジェクト: f-s-p/plaso
    def testProcessSourceExtractWithExtensionsFilter(self):
        """Tests extract with an extensions filter."""
        test_front_end = image_export.ImageExportFrontend()

        options = frontend.Options()
        options.image = self._GetTestFilePath([u'image.qcow2'])
        options.path = self._temp_directory
        options.extensions_string = u'txt'

        test_front_end.ParseOptions(options, source_option=u'image')

        test_front_end.ProcessSource(options)

        expected_extracted_files = sorted(
            [os.path.join(self._temp_directory, u'passwords.txt')])

        extracted_files = self._RecursiveList(self._temp_directory)

        self.assertEqual(sorted(extracted_files), expected_extracted_files)
コード例 #13
0
ファイル: image_export_test.py プロジェクト: f-s-p/plaso
    def testProcessSourceExtractWithSignaturesFilter(self):
        """Tests extract with a signatures filter."""
        test_front_end = image_export.ImageExportFrontend()

        options = frontend.Options()
        options.image = self._GetTestFilePath([u'syslog_image.dd'])
        options.path = self._temp_directory
        options.data_location = self._DATA_PATH
        options.signature_identifiers = u'gzip'

        test_front_end.ParseOptions(options, source_option=u'image')

        test_front_end.ProcessSource(options)

        expected_extracted_files = sorted([
            os.path.join(self._temp_directory, u'logs'),
            os.path.join(self._temp_directory, u'logs', u'sys.tgz')
        ])

        extracted_files = self._RecursiveList(self._temp_directory)

        self.assertEqual(sorted(extracted_files), expected_extracted_files)
コード例 #14
0
    def _TestScanSourceDirectory(self, test_file):
        """Tests the ScanSource function on a directory.

    Args:
      test_file: the path of the test file.
    """
        test_front_end = extraction_frontend.ExtractionFrontend(
            self._input_reader, self._output_writer)

        options = frontend.Options()
        options.source = test_file

        test_front_end.ParseOptions(options)

        test_front_end.ScanSource(options)
        path_spec = test_front_end.GetSourcePathSpec()
        self.assertNotEqual(path_spec, None)
        self.assertEqual(path_spec.location, os.path.abspath(test_file))
        self.assertEqual(path_spec.type_indicator,
                         dfvfs_definitions.TYPE_INDICATOR_OS)
        # pylint: disable=protected-access
        self.assertEqual(test_front_end._partition_offset, None)
コード例 #15
0
ファイル: preg_test.py プロジェクト: cnbird1999/plaso
    def testFrontEnd(self):
        """Test various functions inside the front end object."""
        shell_helper, _ = self._GetHelperAndOutputWriter()
        front_end = shell_helper.tool_front_end

        options = frontend.Options()
        hive_path = self._GetTestFilePath([u'NTUSER.DAT'])
        options.regfile = hive_path

        front_end.ParseOptions(options)

        # Test the --info parameter to the tool.
        info_string = front_end.GetListOfAllPlugins()
        self.assertTrue(u'* Supported Plugins *' in info_string)
        self.assertTrue(u'userassist : Parser for User Assist Registry data' in
                        info_string)
        self.assertTrue(u'services : Parser for services and drivers Registry '
                        in info_string)

        # Get paths to various registry files.
        hive_paths_for_usersassist = set(
            [u'/Documents And Settings/.+/NTUSER.DAT', '/Users/.+/NTUSER.DAT'])
        # Testing functions within the front end, thus need to access protected
        # members.
        # pylint: disable=protected-access
        test_paths_for_userassist = set(
            front_end._GetRegistryFilePaths(u'userassist'))

        self.assertEqual(hive_paths_for_usersassist, test_paths_for_userassist)

        # Set the path to the system registry.
        preg.PregCache.knowledge_base_object.pre_obj.sysregistry = u'C:/Windows/Foo'

        # Test the SOFTWARE hive.
        test_paths = front_end._GetRegistryFilePaths(u'', u'SOFTWARE')
        self.assertEqual(test_paths, [u'C:/Windows/Foo/SOFTWARE'])
コード例 #16
0
ファイル: pshell.py プロジェクト: cnbird1999/plaso
def Main():
    """Start the tool."""
    temp_location = tempfile.gettempdir()

    options = frontend.Options()

    # Set the default options.
    options.buffer_size = 0
    options.debug = False
    options.filename = '.'
    options.file_filter = ''
    options.filter = ''
    options.image = False
    options.image_offset = None
    options.image_offset_bytes = None
    options.old_preprocess = False
    options.output = os.path.join(temp_location, 'wheredidmytimelinego.dump')
    options.output_module = ''
    options.parsers = ''
    options.parse_vss = False
    options.preprocess = False
    options.recursive = False
    options.scan_archives = False
    options.single_process = False
    options.timezone = 'UTC'
    options.workers = 5

    format_str = '[%(levelname)s] (%(processName)-10s) %(message)s'
    logging.basicConfig(format=format_str)

    front_end = pshell.PshellFrontend()

    try:
        front_end.ParseOptions(options, source_option='filename')
        front_end.SetStorageFile(options.output)
    except errors.BadConfigOption as exception:
        logging.error(u'{0:s}'.format(exception))

    # TODO: move to frontend object.
    if options.image and options.image_offset_bytes is None:
        if options.image_offset is not None:
            bytes_per_sector = getattr(options, 'bytes_per_sector', 512)
            options.image_offset_bytes = options.image_offset * bytes_per_sector
        else:
            options.image_offset_bytes = 0

    namespace = {}

    pre_obj = event.PreprocessObject()

    namespace.update(globals())
    namespace.update({
        'frontend': front_end,
        'pre_obj': pre_obj,
        'options': options,
        'find_all_output': FindAllOutputs,
        'parse_file': ParseFile,
        'timestamp_from_event': PrintTimestampFromEvent,
        'message': GetMessageStringsForEventObject
    })

    # Include few random phrases that get thrown in once the user exists the
    # shell.
    _my_random_phrases = [
        u'I haven\'t seen timelines like this since yesterday.',
        u'Timelining is super relaxing.',
        u'Why did I not use the shell before?', u'I like a do da cha cha',
        u'I AM the Shogun of Harlem!',
        (u'It doesn\'t matter if you win or lose, it\'s what you do with your '
         u'dancin\' shoes'),
        u'I have not had a night like that since the seventies.',
        u'Baker Team. They\'re all dead, sir.',
        (u'I could have killed \'em all, I could\'ve killed you. In town '
         u'you\'re the law, out here it\'s me.'),
        (u'Are you telling me that 200 of our men against your boy is a no-win '
         u'situation for us?'),
        u'Hunting? We ain\'t huntin\' him, he\'s huntin\' us!',
        u'You picked the wrong man to push',
        u'Live for nothing or die for something',
        u'I am the Fred Astaire of karate.',
        (u'God gave me a great body and it\'s my duty to take care of my '
         u'physical temple.'),
        u'This maniac should be wearing a number, not a badge',
        u'Imagination is more important than knowledge.',
        u'Do you hate being dead?', u'You\'ve got 5 seconds... and 3 are up.',
        u'He is in a gunfight right now. I\'m gonna have to take a message',
        u'That would be better than losing your teeth',
        u'The less you know, the more you make',
        (u'A SQL query goes into a bar, walks up to two tables and asks, '
         u'"Can I join you?"'), u'This is your captor speaking.',
        (u'If I find out you\'re lying, I\'ll come back and kill you in your '
         u'own kitchen.'), u'That would be better than losing your teeth',
        (u'He\'s the kind of guy who would drink a gallon of gasoline so '
         u'that he can p*ss into your campfire.'),
        u'I\'m gonna take you to the bank, Senator Trent. To the blood bank!',
        u'I missed! I never miss! They must have been smaller than I thought',
        u'Nah. I\'m just a cook.',
        u'Next thing I know, you\'ll be dating musicians.',
        u'Another cold day in hell',
        u'Yeah, but I bet you she doesn\'t see these boys in the choir.',
        u'You guys think you\'re above the law... well you ain\'t above mine!',
        (u'One thought he was invincible... the other thought he could fly... '
         u'They were both wrong'),
        u'To understand what recursion is, you must first understand recursion'
    ]

    arg_description = (
        u'pshell is the interactive session tool that can be used to'
        u'MISSING')

    arg_parser = argparse.ArgumentParser(description=arg_description)

    arg_parser.add_argument('-s',
                            '--storage_file',
                            '--storage-file',
                            dest='storage_file',
                            type=unicode,
                            default=u'',
                            help=u'Path to a plaso storage file.',
                            action='store',
                            metavar='PATH')

    configuration = arg_parser.parse_args()

    if configuration.storage_file:
        store = OpenStorageFile(configuration.storage_file)
        if store:
            namespace.update({'store': store})

    functions = [
        FindAllOutputs, GetEventData, GetParserNames, GetParserObjects,
        OpenOSFile, OpenStorageFile, OpenTskFile, OpenVssFile, ParseFile,
        Pfile2File, PrintTimestamp, PrintTimestampFromEvent
    ]

    functions_strings = []
    for function in functions:
        docstring, _, _ = function.__doc__.partition(u'\n')
        docstring = u'\t{0:s} - {1:s}'.format(function.__name__, docstring)
        functions_strings.append(docstring)
    functions_strings = u'\n'.join(functions_strings)

    banner = (
        u'--------------------------------------------------------------\n'
        u' Welcome to Plaso console - home of the Plaso adventure land.\n'
        u'--------------------------------------------------------------\n'
        u'This is the place where everything is allowed, as long as it is '
        u'written in Python.\n\n'
        u'Objects available:\n\toptions - set of options to the frontend.\n'
        u'\tfrontend - A copy of the pshell frontend.\n'
        u'\n'
        u'All libraries have been imported and can be used, see help(frontend) '
        u'or help(parser).\n'
        u'\n'
        u'Base methods:\n'
        u'{0:s}'
        u'\n\tmessage - Print message strings from an event object.'
        u'\n'
        u'\n'
        u'p.s. typing in "pdb" and pressing enter puts the shell in debug'
        u'mode which causes all exceptions being sent to pdb.\n'
        u'Happy command line console fu-ing.\n\n').format(functions_strings)

    exit_message = u'You are now leaving the winter wonderland.\n\n{}'.format(
        random.choice(_my_random_phrases))

    shell_config = Config()
    # Make slight adjustments to the iPython prompt.
    shell_config.PromptManager.out_template = (
        r'{color.Normal}[{color.Red}\#{color.Normal}]<<< ')
    shell_config.PromptManager.in_template = (
        r'[{color.LightBlue}\T{color.Normal}] {color.LightPurple}\Y2\n'
        r'{color.Normal}[{color.Red}\#{color.Normal}] \$ ')
    shell_config.PromptManager.in2_template = r'.\D.>>>'

    ipshell = InteractiveShellEmbed(user_ns=namespace,
                                    config=shell_config,
                                    banner1=banner,
                                    exit_msg=exit_message)
    ipshell.confirm_exit = False
    # Set autocall to two, making parenthesis not necessary when calling
    # function names (although they can be used and are necessary sometimes,
    # like in variable assignments, etc).
    ipshell.autocall = 2
    ipshell()

    return True
コード例 #17
0
ファイル: pinfo_test.py プロジェクト: cnbird1999/plaso
    def testPrintStorageInformation(self):
        """Tests the PrintStorageInformation function."""
        # Make sure the test outputs UTF-8.
        output_writer = cli_test_lib.TestOutputWriter(encoding=u'utf-8')
        test_tool = pinfo.PinfoTool(output_writer=output_writer)

        options = frontend.Options()
        options.storage_file = self._GetTestFilePath([u'psort_test.out'])

        test_tool.ParseOptions(options)

        test_tool.PrintStorageInformation()

        # TODO: clean up output so that u'...' is not generated.
        expected_output = (
            b'---------------------------------------------------------------------'
            b'-----------\n'
            b'\t\tPlaso Storage Information\n'
            b'---------------------------------------------------------------------'
            b'-----------\n'
            b'Storage file:\t\t{0:s}\n'
            b'Source processed:\tsyslog\nTime of processing:\t'
            b'2014-02-15T04:33:16+00:00\n'
            b'\n'
            b'Collection information:\n'
            b'\tparser_selection = \n'
            b'\tos_detected = N/A\n'
            b'\tconfigured_zone = UTC\n'
            b'\tdebug = False\n'
            b'\tparsers = [u\'sqlite\', u\'winfirewall\', u\'selinux\', '
            b'u\'recycle_bin\', u\'filestat\', u\'syslog\', u\'lnk\', '
            b'u\'xchatscrollback\', u\'symantec_scanlog\', u\'recycle_bin_info2\', '
            b'u\'winevtx\', u\'plist\', u\'bsm_log\', u\'mac_keychain\', '
            b'u\'mac_securityd\', u\'utmp\', u\'asl_log\', u\'opera_global\', '
            b'u\'winjob\', u\'prefetch\', u\'winreg\', u\'msiecf\', u\'bencode\', '
            b'u\'skydrive_log\', u\'openxml\', u\'utmpx\', u\'winevt\', '
            b'u\'hachoir\', u\'opera_typed_history\', u\'mac_appfirewall_log\', '
            b'u\'olecf\', u\'xchatlog\', u\'macwifi\', u\'mactime\', '
            b'u\'java_idx\', u\'mcafee_protection\', u\'skydrive_log_error\']\n'
            b'\tprotobuf_size = 300\n'
            b'\tvss parsing = False\n'
            b'\trecursive = False\n'
            b'\tpreferred_encoding = UTF-8\n'
            b'\tworkers = 12\n'
            b'\toutput_file = psort_test.out\n'
            b'\tversion = 1.1.0-dev_20140213\n'
            b'\tcmd_line = /usr/local/bin/log2timeline.py psort_test.out syslog '
            b'--buffer_size=300\n'
            b'\tpreprocess = False\n'
            b'\truntime = multi threaded\n'
            b'\tmethod = OS collection\n'
            b'\n'
            b'Parser counter information:\n'
            b'\tCounter: total = 15\n'
            b'\tCounter: syslog = 12\n'
            b'\tCounter: filestat = 3\n'
            b'\n'
            b'Store information:\n'
            b'\tNumber of available stores: 7\n'
            b'\tStore information details omitted (to see use: --verbose)\n'
            b'\n'
            b'Preprocessing information omitted (to see use: --verbose).\n'
            b'\n'
            b'No reports stored.\n'
            b'-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+'
            b'-+-+-+-+-+-+').format(options.storage_file.encode(u'utf-8'))

        output = output_writer.ReadOutput()

        self.assertEqual(output, expected_output)