#!/usr/bin/env vpython3
# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from logging import exception
import os
import sys
import unittest
import tempfile
import shutil
sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir, 'perf'))
from core import path_util
path_util.AddPyUtilsToPath()
path_util.AddTracingToPath()
import py_utils
import rename_breakpad
import mock
class RenameBreakpadFilesTestCase(unittest.TestCase):
def setUp(self):
self.breakpad_dir = tempfile.mkdtemp()
self.breakpad_output_dir = tempfile.mkdtemp()
# Directory to unzipped breakpad files.
self.breakpad_unzip_dir = tempfile.mkdtemp(dir=self.breakpad_dir)
def tearDown(self):
shutil.rmtree(self.breakpad_dir)
shutil.rmtree(self.breakpad_output_dir)
def _listSubtree(self, root):
"""Returns absolute paths of files and dirs in root subtree.
"""
files = set()
dirs = set()
for topdir, subdirs, filenames in os.walk(root):
for filename in filenames:
files.add(os.path.join(topdir, filename))
for subdir in subdirs:
dirs.add(os.path.join(topdir, subdir))
return dirs, files
def _assertFilesInInputDir(self,
expected_unmoved_files=frozenset(),
expected_unmoved_dirs=frozenset()):
"""Ensures that |RenameBreakpadFiles| doesn't move files/dirs.
Automatically adds |self.breakpad_unzip_dir| to
|expected_unmoved_dirs| since this file should never be moved.
"""
breakpad_unzip_dir = {self.breakpad_unzip_dir}
expected_unmoved_dirs = expected_unmoved_dirs.union(breakpad_unzip_dir)
unmoved_dirs, unmoved_files = self._listSubtree(self.breakpad_dir)
self.assertEqual(expected_unmoved_files, unmoved_files)
self.assertEqual(expected_unmoved_dirs, unmoved_dirs)
def _assertFilesInOutputDir(self, expected_moved_files=frozenset()):
"""Ensures that |RenameBreakpadFiles| correctly moves files.
"""
moved_files = set(os.listdir(self.breakpad_output_dir))
self.assertEqual(expected_moved_files, moved_files)
def testRenameBreakpadFiles(self):
breakpad_file1 = os.path.join(self.breakpad_unzip_dir, 'file1.breakpad')
breakpad_file2 = os.path.join(self.breakpad_unzip_dir, 'file2.breakpad')
with open(breakpad_file1, 'w') as file1:
file1.write('MODULE Linux x86_64 34984AB4EF948C name1.so')
with open(breakpad_file2, 'w') as file2:
file2.write('MODULE mac x86_64 29e6f9a7ce00f name2.so')
rename_breakpad.RenameBreakpadFiles(self.breakpad_dir,
self.breakpad_output_dir)
self._assertFilesInInputDir()
expected_moved_files = {'34984AB4EF948C.breakpad', '29E6F9A7CE00F.breakpad'}
self._assertFilesInOutputDir(expected_moved_files)
def testRenameBreakpadFilesUpperCaseName(self):
breakpad_file1 = os.path.join(self.breakpad_unzip_dir, 'file1.breakpad')
with open(breakpad_file1, 'w') as file1:
file1.write('MODULE Linux x86_64 12a345b6c7def890 name1.so')
rename_breakpad.RenameBreakpadFiles(self.breakpad_dir,
self.breakpad_output_dir)
self._assertFilesInInputDir()
expected_moved_files = {'12A345B6C7DEF890.breakpad'}
self._assertFilesInOutputDir(expected_moved_files)
def testRenameBreakpadFilesLinuxx86_64(self):
breakpad_file1 = os.path.join(self.breakpad_unzip_dir, 'file1.breakpad.x64')
with open(breakpad_file1, 'w') as file1:
file1.write('MODULE Linux x86_64 34984AB4EF948C name1.so')
rename_breakpad.RenameBreakpadFiles(self.breakpad_dir,
self.breakpad_output_dir)
self._assertFilesInInputDir()
expected_moved_files = {'34984AB4EF948C.breakpad'}
self._assertFilesInOutputDir(expected_moved_files)
def testRenameBreakpadFilesMultipleSubdirs(self):
subdir1 = tempfile.mkdtemp(dir=self.breakpad_unzip_dir)
subdir2 = tempfile.mkdtemp(dir=self.breakpad_unzip_dir)
breakpad_file1 = os.path.join(subdir1, 'file1.breakpad')
breakpad_file2 = os.path.join(subdir2, 'file2.breakpad')
breakpad_file3 = os.path.join(self.breakpad_unzip_dir, 'file3.breakpad')
with open(breakpad_file1, 'w') as file1:
file1.write('MODULE Linux x86_64 48537ABD name1.so')
with open(breakpad_file2, 'w') as file2:
file2.write('MODULE mac x86_64 38ABC9F name2.so')
with open(breakpad_file3, 'w') as file3:
file3.write('MODULE mac x86_64 45DFE name3.so')
rename_breakpad.RenameBreakpadFiles(self.breakpad_dir,
self.breakpad_output_dir)
expected_unmoved_dirs = {subdir1, subdir2}
self._assertFilesInInputDir(expected_unmoved_dirs=expected_unmoved_dirs)
expected_moved_files = {
'48537ABD.breakpad', '38ABC9F.breakpad', '45DFE.breakpad'
}
self._assertFilesInOutputDir(expected_moved_files)
def testRenameBreakpadFilesNonBreakpad(self):
valid_file = os.path.join(self.breakpad_unzip_dir, 'valid.breakpad')
fake_file = os.path.join(self.breakpad_unzip_dir, 'fake.gz')
empty_file = os.path.join(self.breakpad_unzip_dir, 'empty.json')
random_dir = tempfile.mkdtemp(dir=self.breakpad_dir)
non_breakpad_file = os.path.join(random_dir, 'random.txt')
with open(valid_file, 'w') as file1:
file1.write('MODULE mac x86_64 329FDEA987BC name.so')
with open(fake_file, 'w') as file2:
file2.write('random text blah blah blah')
with open(empty_file, 'w'):
pass
with open(non_breakpad_file, 'w') as file3:
file3.write('MODULE mac x86_64 329FDEA987BC name.so')
rename_breakpad.RenameBreakpadFiles(self.breakpad_dir,
self.breakpad_output_dir)
expected_unmoved_files = {fake_file, empty_file, non_breakpad_file}
expected_unmoved_dirs = {random_dir}
self._assertFilesInInputDir(expected_unmoved_files, expected_unmoved_dirs)
expected_moved_files = {'329FDEA987BC.breakpad'}
self._assertFilesInOutputDir(expected_moved_files)
def testRenameBreakpadFilesInvalidBreakpad(self):
valid_file = os.path.join(self.breakpad_unzip_dir, 'valid.breakpad')
empty_file = os.path.join(self.breakpad_unzip_dir, 'empty.breakpad')
no_module_file = os.path.join(self.breakpad_unzip_dir, 'no-module.breakpad')
short_file = os.path.join(self.breakpad_unzip_dir, 'short.breakpad')
with open(valid_file, 'w') as file1:
file1.write('MODULE mac x86_64 1240DF90E9AC39038EF400 Chrome Name')
with open(empty_file, 'w'):
pass
with open(no_module_file, 'w') as file2:
file2.write('NOTMODULE mac x86_64 1240DF90E9AC39038EF400 name')
with open(short_file, 'w') as file3:
file3.write('MODULE mac 1240DF90E9AC39038EF400 name')
rename_breakpad.RenameBreakpadFiles(self.breakpad_dir,
self.breakpad_output_dir)
expected_unmoved_files = {empty_file, no_module_file, short_file}
self._assertFilesInInputDir(expected_unmoved_files)
expected_moved_files = {'1240DF90E9AC39038EF400.breakpad'}
self._assertFilesInOutputDir(expected_moved_files)
def testRenameBreakpadFilesOnlyNonBreakpadAndMisformat(self):
fake_file = os.path.join(self.breakpad_unzip_dir, 'fake.breakpad')
empty_file = os.path.join(self.breakpad_unzip_dir, 'empty.breakpad')
no_module_file = os.path.join(self.breakpad_unzip_dir, 'no-module.breakpad')
short_file = os.path.join(self.breakpad_unzip_dir, 'short.breakpad')
random_dir = tempfile.mkdtemp(dir=self.breakpad_dir)
non_breakpad_file = os.path.join(random_dir, 'random.txt')
with open(fake_file, 'w') as file1:
file1.write('random text blah blah blah')
with open(empty_file, 'w'):
pass
with open(no_module_file, 'w') as file2:
file2.write('NOTMODULE mac x86_64 1240DF90E9AC39038EF400 name')
with open(short_file, 'w') as file3:
file3.write('MODULE mac 1240DF90E9AC39038EF400 name')
with open(non_breakpad_file, 'w') as file4:
file4.write('MODULE mac x86_64 1240DF90E9AC39038EF400 Chrome Name')
rename_breakpad.RenameBreakpadFiles(self.breakpad_dir,
self.breakpad_output_dir)
expected_unmoved_files = {
fake_file, non_breakpad_file, empty_file, no_module_file, short_file
}
expected_unmoved_dirs = {random_dir}
self._assertFilesInInputDir(expected_unmoved_files, expected_unmoved_dirs)
self._assertFilesInOutputDir()
def testRenameBreakpadFilesRepeatedModuleID(self):
breakpad_file1 = os.path.join(self.breakpad_unzip_dir, 'file1.breakpad')
breakpad_file2 = os.path.join(self.breakpad_unzip_dir, 'file2.breakpad')
with open(breakpad_file1, 'w') as file1:
file1.write('MODULE mac x86_64 12ABC8987DE name.so')
with open(breakpad_file2, 'w') as file2:
file2.write('MODULE mac x86_64 12ABC8987DE name.so')
# Check that the right exception is raised.
exception_msg = ('Symbol file modules ids are not unique')
with self.assertRaises(AssertionError) as e:
rename_breakpad.RenameBreakpadFiles(self.breakpad_dir,
self.breakpad_output_dir)
self.assertIn(exception_msg, str(e.exception))
# Check breakpad file with repeated module id is not moved. More
# complicated because either of the breakpad files could be moved.
self.assertTrue(
os.path.isfile(breakpad_file1) ^ os.path.isfile(breakpad_file2))
# Ensure one of the breakpad module files got moved. No matter which
# breakpad file got moved, it will have the same new module-based filename.
expected_moved_files = {'12ABC8987DE.breakpad'}
self._assertFilesInOutputDir(expected_moved_files)
def testRenameBreakpadFilesRepeatedModuleIDMultipleSubdirs(self):
subdir1 = tempfile.mkdtemp(dir=self.breakpad_unzip_dir)
subdir2 = tempfile.mkdtemp(dir=self.breakpad_unzip_dir)
breakpad_file1 = os.path.join(subdir1, 'file1.breakpad')
breakpad_file2 = os.path.join(subdir2, 'file2.breakpad')
with open(breakpad_file1, 'w') as file1:
file1.write('MODULE mac x86_64 ABCE4853004895 name.so')
with open(breakpad_file2, 'w') as file2:
file2.write('MODULE mac x86_64 ABCE4853004895 name.so')
# Check that the right exception is raised.
exception_msg = ('Symbol file modules ids are not unique')
with self.assertRaises(AssertionError) as e:
rename_breakpad.RenameBreakpadFiles(self.breakpad_dir,
self.breakpad_output_dir)
self.assertIn(exception_msg, str(e.exception))
# Check breakpad file with repeated module id is not moved. More
# complicated because either of the breakpad files could be moved.
self.assertTrue(
os.path.isfile(breakpad_file1) ^ os.path.isfile(breakpad_file2))
# Ensure one of the breakpad module files got moved. No matter which
# breakpad file got moved, it will have the same new module-based filename.
expected_moved_files = {'ABCE4853004895.breakpad'}
self._assertFilesInOutputDir(expected_moved_files)
def testRenameBreakpadFilesInputDirEqualsOutputDir(self):
subdir = tempfile.mkdtemp(dir=self.breakpad_unzip_dir)
breakpad_file1 = os.path.join(self.breakpad_unzip_dir, 'file1.breakpad')
breakpad_file2 = os.path.join(subdir, 'file2.breakpad')
with open(breakpad_file1, 'w') as file1:
file1.write('MODULE Linux x86_64 34984AB4EF948C name1.so')
with open(breakpad_file2, 'w') as file2:
file2.write('MODULE mac x86_64 29e6f9a7ce00f name2.so')
rename_breakpad.RenameBreakpadFiles(self.breakpad_dir, self.breakpad_dir)
# All files should be moved into |self.breakpad_dir|.
moved_breakpad1 = os.path.join(self.breakpad_dir, '34984AB4EF948C.breakpad')
moved_breakpad2 = os.path.join(self.breakpad_dir, '29E6F9A7CE00F.breakpad')
expected_files = {moved_breakpad1, moved_breakpad2}
expected_unmoved_dirs = {subdir}
self._assertFilesInInputDir(expected_files, expected_unmoved_dirs)
# No files should be moved to |self.breakpad_output_dir|.
self._assertFilesInOutputDir()
def testRenameBreakpadFilesAllUnmoved(self):
breakpad_file1 = os.path.join(self.breakpad_unzip_dir, 'file1.breakpad')
breakpad_file2 = os.path.join(self.breakpad_unzip_dir, 'file2.breakpad')
with open(breakpad_file1, 'w') as file1:
file1.write('MODULE Linux x86_64 34984AB4EF948C name1.so')
with open(breakpad_file2, 'w') as file2:
file2.write('MODULE mac x86_64 29e6f9a7ce00f name2.so')
rename_breakpad.RenameBreakpadFiles(self.breakpad_dir,
self.breakpad_unzip_dir)
# All files should be renamed but not moved.
unmoved_breakpad1 = os.path.join(self.breakpad_unzip_dir,
'34984AB4EF948C.breakpad')
unmoved_breakpad2 = os.path.join(self.breakpad_unzip_dir,
'29E6F9A7CE00F.breakpad')
expected_renamed_files = {unmoved_breakpad1, unmoved_breakpad2}
self._assertFilesInInputDir(expected_renamed_files)
# No files should be moved to |self.breakpad_output_dir|.
self._assertFilesInOutputDir()
if __name__ == '__main__':
unittest.main()