#!/usr/bin/env vpython
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Tests for process_profiles.py."""

import collections
import unittest

import process_profiles

from test_utils import (ProfileFile,
                        SimpleTestSymbol,
                        TestSymbolOffsetProcessor,
                        TestProfileManager)

class ProcessProfilesTestCase(unittest.TestCase):
  START_SYMBOL = 'linker_script_start_of_text'

  def setUp(self):
    self.symbol_0 = SimpleTestSymbol(self.START_SYMBOL, 0, 0)
    self.symbol_1 = SimpleTestSymbol('1', 6, 16)
    self.symbol_2 = SimpleTestSymbol('2', 32, 8)
    self.symbol_3 = SimpleTestSymbol('3', 40, 12)
    self.offset_to_symbol_info = (
        [None] * 3 + [self.symbol_1] * 8 + [None] * 5 + [self.symbol_2] * 4 +
        [self.symbol_3] * 6)
    self.symbol_infos = [self.symbol_0, self.symbol_1,
                         self.symbol_2, self.symbol_3]
    self._file_counter = 0

  def MakeAnnotatedOffset(self, offset, counts):
    ao = process_profiles.ProfileManager.AnnotatedOffset(offset)
    ao._count = counts
    return ao

  def testGetOffsetToSymbolInfo(self):
    processor = TestSymbolOffsetProcessor(self.symbol_infos)
    self.assertListEqual(self.offset_to_symbol_info,
                         processor._GetDumpOffsetToSymbolInfo())

  def testOverlappingSymbols(self):
    symbol_1 = SimpleTestSymbol(self.START_SYMBOL, 6, 8)
    symbol_2 = SimpleTestSymbol('2', 10, 10)
    processor = TestSymbolOffsetProcessor([symbol_1, symbol_2])
    self.assertListEqual([symbol_1] * 4 + [symbol_2] * 3,
                         processor._GetDumpOffsetToSymbolInfo())

  def testSymbolsBeforeStart(self):
    self.symbol_infos = [SimpleTestSymbol(s.name, s.offset + 8, s.size)
                         for s in self.symbol_infos]
    self.symbol_infos.append(SimpleTestSymbol('early', 0, 4))
    processor = TestSymbolOffsetProcessor(self.symbol_infos)
    self.assertRaises(AssertionError, processor._GetDumpOffsetToSymbolInfo)

  def testGetReachedOffsetsFromDump(self):
    processor = TestSymbolOffsetProcessor(self.symbol_infos)
    # 2 hits for symbol_1, 0 for symbol_2, 1 for symbol_3
    dump = [8, 12, 48]
    reached = processor.GetReachedOffsetsFromDump(dump)
    self.assertListEqual([self.symbol_1.offset, self.symbol_3.offset], reached)
    # Ordering matters, no repetitions
    dump = [48, 12, 8, 12, 8, 16]
    reached = processor.GetReachedOffsetsFromDump(dump)
    self.assertListEqual([self.symbol_3.offset, self.symbol_1.offset], reached)

  def testSymbolNameToPrimary(self):
    symbol_infos = [SimpleTestSymbol('1', 8, 16),
                    SimpleTestSymbol('AnAlias', 8, 16),
                    SimpleTestSymbol('Another', 40, 16)]
    processor = TestSymbolOffsetProcessor(symbol_infos)
    self.assertDictEqual({8: symbol_infos[0],
                          40: symbol_infos[2]}, processor.OffsetToPrimaryMap())

  def testGetOrderedSymbols(self):
    processor = TestSymbolOffsetProcessor(self.symbol_infos)
    self.assertListEqual(['1', '3', self.START_SYMBOL],
                         processor.GetOrderedSymbols([7, 41, 5, 0]))

  def testOffsetToSymbolsMap(self):
    symbol_infos = [SimpleTestSymbol('1', 8, 16),
                    SimpleTestSymbol('AnAlias', 8, 16),
                    SimpleTestSymbol('Another', 40, 16)]
    processor = TestSymbolOffsetProcessor(symbol_infos)
    self.assertDictEqual({8: [symbol_infos[0], symbol_infos[1]],
                          40: [symbol_infos[2]]},
                         processor.OffsetToSymbolsMap())

  def testPrimarySizeMismatch(self):
    symbol_infos = [SimpleTestSymbol('1', 8, 16),
                    SimpleTestSymbol('AnAlias', 8, 32)]
    processor = TestSymbolOffsetProcessor(symbol_infos)
    self.assertRaises(AssertionError, processor.OffsetToPrimaryMap)
    symbol_infos = [SimpleTestSymbol('1', 8, 0),
                    SimpleTestSymbol('2', 8, 32),
                    SimpleTestSymbol('3', 8, 32),
                    SimpleTestSymbol('4', 8, 0),]
    processor = TestSymbolOffsetProcessor(symbol_infos)
    self.assertDictEqual({8: symbol_infos[1]}, processor.OffsetToPrimaryMap())

  def testMatchSymbols(self):
    symbols = [SimpleTestSymbol('W', 30, 10),
               SimpleTestSymbol('Y', 60, 5),
               SimpleTestSymbol('X', 100, 10)]
    processor = TestSymbolOffsetProcessor(symbols)
    self.assertListEqual(symbols[1:3],
                         processor.MatchSymbolNames(['Y', 'X']))

  def testSymbolsSize(self):
    symbols = [SimpleTestSymbol('W', 10, 1),
               SimpleTestSymbol('X', 20, 2),
               SimpleTestSymbol('Y', 30, 4),
               SimpleTestSymbol('Z', 40, 8)]
    processor = TestSymbolOffsetProcessor(symbols)
    self.assertEqual(13, processor.SymbolsSize(['W', 'Y', 'Z']))

  def testMedian(self):
    self.assertEquals(None, process_profiles._Median([]))
    self.assertEquals(5, process_profiles._Median([5]))
    self.assertEquals(5, process_profiles._Median([1, 5, 20]))
    self.assertEquals(5, process_profiles._Median([4, 6]))
    self.assertEquals(5, process_profiles._Median([1, 4, 6, 100]))
    self.assertEquals(5, process_profiles._Median([1, 4, 5, 6, 100]))

  def testRunGroups(self):
    files = [ProfileFile(40, 0), ProfileFile(100, 0),
             ProfileFile(200, 1), ProfileFile(35, 1),
             ProfileFile(42, 0), ProfileFile(95, 0)]
    mgr = process_profiles.ProfileManager(files)
    mgr._ComputeRunGroups()
    self.assertEquals(3, len(mgr._run_groups))
    self.assertEquals(3, len(mgr._run_groups[0].Filenames()))
    self.assertEquals(2, len(mgr._run_groups[1].Filenames()))
    self.assertEquals(1, len(mgr._run_groups[2].Filenames()))
    self.assertTrue(files[0] in mgr._run_groups[0].Filenames())
    self.assertTrue(files[3] in mgr._run_groups[0].Filenames())
    self.assertTrue(files[4] in mgr._run_groups[0].Filenames())
    self.assertTrue(files[1] in mgr._run_groups[1].Filenames())
    self.assertTrue(files[5] in mgr._run_groups[1].Filenames())
    self.assertTrue(files[2] in mgr._run_groups[2].Filenames())

  def testRunGroupSanity(self):
    files = []
    # Generate 20 sets of files in groups separated by 60s.
    for ts_base in xrange(0, 20):
      ts = ts_base * 60
      files.extend([ProfileFile(ts, 0, 'browser'),
                    ProfileFile(ts + 1, 0, 'renderer'),
                    ProfileFile(ts + 2, 1, 'browser'),
                    ProfileFile(ts + 3, 0, 'gpu'),
                    ProfileFile(ts + 2, 1, 'renderer'),
                    ProfileFile(ts + 5, 1, 'gpu')])
    # The following call should not assert.
    process_profiles.ProfileManager(files)._ComputeRunGroups()

    files.extend([ProfileFile(20 * 60, 0, 'browser'),
                  ProfileFile(20 * 60 + 2, 1, 'renderer'),
                  ProfileFile(21 * 60, 0, 'browser')] +
                 [ProfileFile(22 * 60, 0, 'renderer')
                  for _ in xrange(0, 10)])

    self.assertRaises(AssertionError,
                      process_profiles.ProfileManager(files)._ComputeRunGroups)

  def testReadOffsets(self):
    mgr = TestProfileManager({
        ProfileFile(30, 0): [1, 3, 5, 7],
        ProfileFile(40, 1): [8, 10],
        ProfileFile(50, 0): [13, 15]})
    self.assertListEqual([1, 3, 5, 7, 8, 10, 13, 15],
                         mgr.GetMergedOffsets())
    self.assertListEqual([8, 10], mgr.GetMergedOffsets(1))
    self.assertListEqual([], mgr.GetMergedOffsets(2))

  def testRunGroupOffsets(self):
    mgr = TestProfileManager({
        ProfileFile(30, 0): [1, 2, 3, 4],
        ProfileFile(150, 0): [9, 11, 13],
        ProfileFile(40, 1): [5, 6, 7]})
    offsets_list = mgr.GetRunGroupOffsets()
    self.assertEquals(2, len(offsets_list))
    self.assertListEqual([1, 2, 3, 4, 5, 6, 7], offsets_list[0])
    self.assertListEqual([9, 11, 13], offsets_list[1])
    offsets_list = mgr.GetRunGroupOffsets(0)
    self.assertEquals(2, len(offsets_list))
    self.assertListEqual([1, 2, 3, 4], offsets_list[0])
    self.assertListEqual([9, 11, 13], offsets_list[1])
    offsets_list = mgr.GetRunGroupOffsets(1)
    self.assertEquals(2, len(offsets_list))
    self.assertListEqual([5, 6, 7], offsets_list[0])
    self.assertListEqual([], offsets_list[1])

  def testSorted(self):
    # The fact that the ProfileManager sorts by filename is implicit in the
    # other tests. It is tested explicitly here.
    mgr = TestProfileManager({
        ProfileFile(40, 0): [1, 2, 3, 4],
        ProfileFile(150, 0): [9, 11, 13],
        ProfileFile(30, 1): [5, 6, 7]})
    offsets_list = mgr.GetRunGroupOffsets()
    self.assertEquals(2, len(offsets_list))
    self.assertListEqual([5, 6, 7, 1, 2, 3, 4], offsets_list[0])

  def testPhases(self):
    mgr = TestProfileManager({
        ProfileFile(40, 0): [],
        ProfileFile(150, 0): [],
        ProfileFile(30, 1): [],
        ProfileFile(30, 2): [],
        ProfileFile(30, 0): []})
    self.assertEquals(set([0,1,2]), mgr.GetPhases())

  def testGetAnnotatedOffsets(self):
    mgr = TestProfileManager({
        ProfileFile(40, 0, ''): [1, 2, 3],
        ProfileFile(50, 1, ''): [3, 4, 5],
        ProfileFile(51, 0, 'renderer'): [2, 3, 6],
        ProfileFile(51, 1, 'gpu-process'): [6, 7],
        ProfileFile(70, 0, ''): [2, 8, 9],
        ProfileFile(70, 1, ''): [9]})
    offsets = mgr.GetAnnotatedOffsets()
    self.assertListEqual([
        self.MakeAnnotatedOffset(1, {(0, 'browser'): 1}),
        self.MakeAnnotatedOffset(2, {(0, 'browser'): 2,
                                     (0, 'renderer'): 1}),
        self.MakeAnnotatedOffset(3, {(0, 'browser'): 1,
                                     (1, 'browser'): 1,
                                     (0, 'renderer'): 1}),
        self.MakeAnnotatedOffset(4, {(1, 'browser'): 1}),
        self.MakeAnnotatedOffset(5, {(1, 'browser'): 1}),
        self.MakeAnnotatedOffset(6, {(0, 'renderer'): 1,
                                     (1, 'gpu-process'): 1}),
        self.MakeAnnotatedOffset(7, {(1, 'gpu-process'): 1}),
        self.MakeAnnotatedOffset(8, {(0, 'browser'): 1}),
        self.MakeAnnotatedOffset(9, {(0, 'browser'): 1,
                                     (1, 'browser'): 1})],
                         offsets)
    self.assertListEqual(['browser', 'renderer'],
                         sorted(offsets[1].Processes()))
    self.assertListEqual(['browser'], list(offsets[0].Processes()))
    self.assertListEqual([0], list(offsets[1].Phases()))
    self.assertListEqual([0, 1], sorted(offsets[2].Phases()))
    self.assertListEqual([0, 1], sorted(mgr.GetPhases()))


if __name__ == '__main__':
  unittest.main()
