• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (C) 2020 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#   http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14import io
15import textwrap
16import unittest
17
18from perf2cfg import analyze
19from perf2cfg import edit
20
21
22def empty_analyzer():
23    return analyze.RecordAnalyzer()
24
25
26def populated_analyzer():
27    analyzer = analyze.RecordAnalyzer()
28    analyzer.target_arch = 'aarch64'
29    samples = [
30        ('void hcf()', 4, 'cpu-cycles', 90),
31        ('void hcf()', 8, 'cpu-cycles', 10),
32        ('void hcf()', 8, 'cache-misses', 100),
33    ]
34
35    for sample in samples:
36        analyzer.record_sample(*sample)
37
38    return analyzer
39
40
41def edit_string(analyzer, input_string):
42    input_stream = io.StringIO(input_string)
43    output_stream = io.StringIO()
44
45    editor = edit.CfgEditor(analyzer, input_stream, output_stream)
46    editor.edit()
47
48    return output_stream
49
50
51class TestEdit(unittest.TestCase):
52
53    def test_empty_file(self):
54        output_stream = edit_string(empty_analyzer(), '')
55        self.assertEqual(output_stream.getvalue(), '')
56
57    def test_wrong_filetype(self):
58        with self.assertLogs() as ctx:
59            edit_string(
60                empty_analyzer(), """<!DOCTYPE html>
61                <html>
62                <head>
63                  <title>I'm not a CFG file</title>
64                </head>
65                </html>""")
66
67        self.assertEqual(
68            ctx.output,
69            ['ERROR:root:Line 1: Expected a `begin_compilation` directive'])
70
71    def test_no_architecture(self):
72        with self.assertLogs() as ctx:
73            edit_string(
74                populated_analyzer(), """begin_compilation
75                  name "void noMetadata()"
76                end_compilation""")
77
78        self.assertEqual(ctx.output, [
79            'WARNING:root:Could not deduce the CFG file ISA, assuming it is '
80            'compatible with the target architecture aarch64'
81        ])
82
83    def test_wrong_architecture(self):
84        with self.assertLogs() as ctx:
85            edit_string(
86                populated_analyzer(), """begin_compilation
87                  name "isa:x86_64"
88                end_compilation""")
89
90        self.assertEqual(ctx.output, [
91            'ERROR:root:The CFG file ISA x86_64 is incompatible with the '
92            'target architecture aarch64'
93        ])
94
95    def test_annotate_method(self):
96        with self.assertLogs() as ctx:
97            output_stream = edit_string(
98                populated_analyzer(),
99                textwrap.dedent("""\
100                    begin_compilation
101                      name "isa:arm64 isa_features:a53,crc,-lse,-fp16,-dotprod,-sve"
102                    end_compilation
103                    begin_compilation
104                      name "void hcf()"
105                    end_compilation
106                    begin_cfg
107                      name "disassembly (after)"
108                      begin_block
109                        flags
110                        begin_HIR
111                          0 0 NOPSlide dex_pc:0 loop:none
112                          0x00000000: d503201f nop
113                          0x00000004: d503201f nop
114                          0x00000008: d503201f nop
115                          <|@
116                        end_HIR
117                      end_block
118                    end_cfg"""))
119
120        self.assertEqual(ctx.output, ['INFO:root:Annotated void hcf()'])
121        self.assertEqual(
122            output_stream.getvalue(),
123            textwrap.dedent("""\
124                begin_compilation
125                  name "isa:arm64 isa_features:a53,crc,-lse,-fp16,-dotprod,-sve"
126                end_compilation
127                begin_compilation
128                  name "[cpu-cycles: 100.00%, cache-misses: 100.00%] void hcf()"
129                end_compilation
130                begin_cfg
131                  name "disassembly (after)"
132                  begin_block
133                    flags "cpu-cycles: 100.00%" "cache-misses: 100.00%" "HI"
134                    begin_HIR
135                      0 0 NOPSlide dex_pc:0 loop:none
136                _                           0x00000000: d503201f nop
137                cpu-cycles:     90 (90.00%) 0x00000004: d503201f nop
138                cache-misses:     0 (0.00%)
139                cpu-cycles:     10 (10.00%) 0x00000008: d503201f nop
140                cache-misses: 100 (100.00%)
141                      <|@
142                    end_HIR
143                  end_block
144                end_cfg"""))
145