| #!/usr/bin/env python2 |
| # -*- coding: utf-8 -*- |
| """Tests for heatmap_generator.py.""" |
| |
| from __future__ import division, print_function |
| |
| import os |
| import unittest |
| |
| import heatmap_generator |
| |
| |
| def _write_perf_record(pid, tid, addr, fp): |
| print( |
| '0 0 0 0 PERF_RECORD_MMAP2 %d/%d: ' |
| '[%x(0x100) @ 0x0 0:0 0 0] ' |
| 'r-xp /opt/google/chrome/chrome\n' % (pid, tid, addr), |
| file=fp) |
| |
| |
| def _write_perf_fork(pid_from, tid_from, pid_to, tid_to, fp): |
| print( |
| '0 0 0 0 PERF_RECORD_FORK(%d:%d):(%d:%d)\n' % (pid_to, tid_to, pid_from, |
| tid_from), |
| file=fp) |
| |
| |
| def _write_perf_exit(pid_from, tid_from, pid_to, tid_to, fp): |
| print( |
| '0 0 0 0 PERF_RECORD_EXIT(%d:%d):(%d:%d)\n' % (pid_to, tid_to, pid_from, |
| tid_from), |
| file=fp) |
| |
| |
| def _write_perf_sample(pid, tid, addr, fp): |
| print( |
| '0 0 0 0 PERF_RECORD_SAMPLE(IP, 0x2): ' |
| '%d/%d: %x period: 100000 addr: 0' % (pid, tid, addr), |
| file=fp) |
| print(' ... thread: chrome:%d' % tid, file=fp) |
| print(' ...... dso: /opt/google/chrome/chrome\n', file=fp) |
| |
| |
| def _heatmap(file_name, page_size=4096): |
| generator = heatmap_generator.HeatmapGenerator( |
| file_name, page_size, '', log_level='none') # Don't log to stdout |
| generator.draw() |
| |
| |
| def _cleanup(file_name): |
| os.remove(file_name) |
| os.remove('out.txt') |
| os.remove('inst-histo.txt') |
| os.remove('heat_map.png') |
| os.remove('timeline.png') |
| |
| |
| class Tests(unittest.TestCase): |
| """All of our tests for heatmap_generator.""" |
| |
| def test_with_one_mmap_one_sample(self): |
| """Tests one perf record and one sample.""" |
| fname = 'test.txt' |
| with open(fname, 'w') as f: |
| _write_perf_record(101, 101, 0xABCD000, f) |
| _write_perf_sample(101, 101, 0xABCD101, f) |
| _heatmap(fname) |
| self.assertIn('out.txt', os.listdir('.')) |
| with open('out.txt') as f: |
| lines = f.readlines() |
| self.assertTrue(len(lines) == 1) |
| self.assertIn('101/101: 1 0', lines[0]) |
| _cleanup(fname) |
| |
| def test_with_one_mmap_multiple_samples(self): |
| """Tests one perf record and three samples.""" |
| fname = 'test.txt' |
| with open(fname, 'w') as f: |
| _write_perf_record(101, 101, 0xABCD000, f) |
| _write_perf_sample(101, 101, 0xABCD101, f) |
| _write_perf_sample(101, 101, 0xABCD102, f) |
| _write_perf_sample(101, 101, 0xABCE102, f) |
| _heatmap(fname) |
| self.assertIn('out.txt', os.listdir('.')) |
| with open('out.txt') as f: |
| lines = f.readlines() |
| self.assertTrue(len(lines) == 3) |
| self.assertIn('101/101: 1 0', lines[0]) |
| self.assertIn('101/101: 2 0', lines[1]) |
| self.assertIn('101/101: 3 4096', lines[2]) |
| _cleanup(fname) |
| |
| def test_with_fork_and_exit(self): |
| """Tests perf fork and perf exit.""" |
| fname = 'test_fork.txt' |
| with open(fname, 'w') as f: |
| _write_perf_record(101, 101, 0xABCD000, f) |
| _write_perf_fork(101, 101, 202, 202, f) |
| _write_perf_sample(101, 101, 0xABCD101, f) |
| _write_perf_sample(202, 202, 0xABCE101, f) |
| _write_perf_exit(202, 202, 202, 202, f) |
| _heatmap(fname) |
| self.assertIn('out.txt', os.listdir('.')) |
| with open('out.txt') as f: |
| lines = f.readlines() |
| self.assertTrue(len(lines) == 2) |
| self.assertIn('101/101: 1 0', lines[0]) |
| self.assertIn('202/202: 2 4096', lines[1]) |
| _cleanup(fname) |
| |
| def test_histogram(self): |
| """Tests if the tool can generate correct histogram. |
| |
| In the tool, histogram is generated from statistics |
| of perf samples (saved to out.txt). The histogram is |
| generated by perf-to-inst-page.sh and saved to |
| inst-histo.txt. It will be used to draw heat maps. |
| """ |
| fname = 'test_histo.txt' |
| with open(fname, 'w') as f: |
| _write_perf_record(101, 101, 0xABCD000, f) |
| for i in range(0, 100): |
| _write_perf_sample(101, 101, 0xABCD000 + i, f) |
| _write_perf_sample(101, 101, 0xABCE000 + i, f) |
| _write_perf_sample(101, 101, 0xABFD000 + i, f) |
| _write_perf_sample(101, 101, 0xAFCD000 + i, f) |
| _heatmap(fname) |
| self.assertIn('inst-histo.txt', os.listdir('.')) |
| with open('inst-histo.txt') as f: |
| lines = f.readlines() |
| self.assertTrue(len(lines) == 4) |
| self.assertIn('100 0', lines[0]) |
| self.assertIn('100 4096', lines[1]) |
| self.assertIn('100 196608', lines[2]) |
| self.assertIn('100 4194304', lines[3]) |
| _cleanup(fname) |
| |
| def test_histogram_two_mb_page(self): |
| """Tests handling of 2MB page.""" |
| fname = 'test_histo.txt' |
| with open(fname, 'w') as f: |
| _write_perf_record(101, 101, 0xABCD000, f) |
| for i in range(0, 100): |
| _write_perf_sample(101, 101, 0xABCD000 + i, f) |
| _write_perf_sample(101, 101, 0xABCE000 + i, f) |
| _write_perf_sample(101, 101, 0xABFD000 + i, f) |
| _write_perf_sample(101, 101, 0xAFCD000 + i, f) |
| _heatmap(fname, page_size=2 * 1024 * 1024) |
| self.assertIn('inst-histo.txt', os.listdir('.')) |
| with open('inst-histo.txt') as f: |
| lines = f.readlines() |
| self.assertTrue(len(lines) == 2) |
| self.assertIn('300 0', lines[0]) |
| self.assertIn('100 4194304', lines[1]) |
| _cleanup(fname) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |