blob: be76ad60dfd1c23ff1fc6410a5668bccb9f0d584 [file] [log] [blame]
#!/usr/bin/python
#
# Copyright 2010 Google Inc. All Rights Reserved.
__author__ = "asharif@google.com (Ahmad Sharif)"
import os
import random
import shutil
import tempfile
import unittest
from utils import command_executer
from utils import misc
class DivideAndMergeProfilesTest(unittest.TestCase):
def tearDown(self):
shutil.rmtree(self._program_dir)
for profile_dir in self._profile_dirs:
shutil.rmtree(profile_dir)
def setUp(self):
self._ce = command_executer.GetCommandExecuter()
self._program_dir = tempfile.mkdtemp()
self._writeProgram()
self._writeMakefile()
with misc.WorkingDirectory(self._program_dir):
self._ce.RunCommand("make")
num_profile_dirs = 2
self._profile_dirs = []
for i in range(num_profile_dirs):
profile_dir = tempfile.mkdtemp()
command = ("GCOV_PREFIX_STRIP=%s GCOV_PREFIX=$(/bin/pwd) "
" %s/program" %
(profile_dir.count("/"),
self._program_dir))
with misc.WorkingDirectory(profile_dir):
self._ce.RunCommand(command)
self._profile_dirs.append(profile_dir)
self._merge_program = "/home/build/static/projects/crosstool/profile-merge/v14.5/profile_merge.par"
def _writeMakefile(self):
makefile_contents = """
CC = gcc
CFLAGS = -fprofile-generate
SRCS=$(wildcard *.c)
OBJS=$(SRCS:.c=.o)
all: program
program: $(OBJS)
$(CC) -o $@ $^ $(CFLAGS)
%.o: %.c
$(CC) -c -o $@ $^ $(CFLAGS)"""
makefile = os.path.join(self._program_dir, "Makefile")
with open(makefile, "w") as f:
print >> f, makefile_contents
def _writeProgram(self, num_files=100):
for i in range(num_files):
current_file = os.path.join(self._program_dir, "%s.c" % i)
with open(current_file, "w") as f:
if i != num_files - 1:
print >> f, "extern void foo%s();" % (i + 1)
print >> f, "void foo%s(){foo%s();}" % (i, i + 1)
else:
print >> f, "void foo%s(){printf(\"\");}" % i
if i == 0:
print >> f, "int main(){foo%s(); return 0;}" % i
def testMerge(self):
reference_output = self._getReferenceOutput()
my_output = self._getMyOutput()
ret = self._diffOutputs(reference_output, my_output)
shutil.rmtree(my_output)
shutil.rmtree(reference_output)
self.assertTrue(ret == 0)
def _diffOutputs(self, reference, mine):
command = "diff -uNr %s %s" % (reference, mine)
return self._ce.RunCommand(command)
def _getMyOutput(self, args=""):
my_output = tempfile.mkdtemp()
my_merge_program = os.path.join(os.path.dirname(__file__),
"divide_and_merge_profiles.py")
command = ("python %s --inputs=%s --output=%s "
"--chunk_size=10 "
"--merge_program=%s "
"%s" %
(my_merge_program,
",".join(self._profile_dirs),
my_output,
self._merge_program,
args))
self._ce.RunCommand(command)
return my_output
def _getReferenceOutput(self, args=""):
# First do a regular merge.
reference_output = tempfile.mkdtemp()
command = ("%s --inputs=%s --output=%s %s" %
(self._merge_program,
",".join(self._profile_dirs),
reference_output,
args))
self._ce.RunCommand(command)
return reference_output
def testMergeWithMultipliers(self):
num_profiles = len(self._profile_dirs)
multipliers = [str(random.randint(0, num_profiles)) \
for _ in range(num_profiles)]
args = "--multipliers=%s" % ",".join(multipliers)
reference_output = self._getReferenceOutput(args)
my_output = self._getMyOutput(args)
ret = self._diffOutputs(reference_output, my_output)
shutil.rmtree(my_output)
shutil.rmtree(reference_output)
self.assertTrue(ret == 0)
if __name__ == "__main__":
unittest.main()