| #!/usr/bin/env python |
| # Copyright 2019 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import unittest |
| |
| from codegen import EventInfo |
| from codegen import MetricInfo |
| from builders_template import HEADER as BUILDERS_HEADER_TEMPLATE |
| from builders_template import IMPL as BUILDERS_IMPL_TEMPLATE |
| from decode_template import HEADER as DECODE_HEADER_TEMPLATE |
| from decode_template import IMPL as DECODE_IMPL_TEMPLATE |
| import ukm_model |
| import gen_builders |
| import os |
| |
| _FILE_DIR = os.path.dirname(__file__) |
| |
| class GenBuildersTest(unittest.TestCase): |
| def testFilterObsoleteMetrics(self): |
| data = gen_builders.ReadFilteredData(_FILE_DIR + '/ukm.xml') |
| for event in data[ukm_model._EVENT_TYPE.tag]: |
| self.assertTrue(ukm_model.IsNotObsolete(event)) |
| for metric in event[ukm_model._METRIC_TYPE.tag]: |
| self.assertTrue(ukm_model.IsNotObsolete(metric)) |
| |
| def testGenerateCode(self): |
| relpath = '.' |
| with open(_FILE_DIR + '/ukm.xml') as f: |
| data = ukm_model.UKM_XML_TYPE.Parse(f.read()) |
| event = data[ukm_model._EVENT_TYPE.tag][0] |
| metric = event[ukm_model._METRIC_TYPE.tag][0] |
| self.assertIsNotNone(event) |
| self.assertIsNotNone(metric) |
| eventInfo = EventInfo(event) |
| metricInfo = MetricInfo(metric) |
| |
| # Not using codegen.Template.WriteFile to avoid non-deterministic test |
| # behaviour after writing to disk. |
| builders_header_output = BUILDERS_HEADER_TEMPLATE._StampFileCode( |
| relpath, data) |
| self.assertIsNotNone(builders_header_output) |
| self.assertIn("// Generated from gen_builders.py. DO NOT EDIT!", |
| builders_header_output) |
| self.assertIn("namespace builders", builders_header_output) |
| self.assertIn( |
| """ |
| class {name} final : public ::ukm::internal::UkmEntryBuilderBase {{ |
| public: |
| explicit {name}(ukm::SourceId source_id); |
| explicit {name}(ukm::SourceIdObj source_id); |
| ~{name}() override; |
| |
| static const char kEntryName[]; |
| static constexpr uint64_t kEntryNameHash = UINT64_C({hash});""".format( |
| name=eventInfo.name, hash=eventInfo.hash), builders_header_output) |
| |
| self.assertIn( |
| """ |
| static const char k{metricName}Name[]; |
| static constexpr uint64_t k{metricName}NameHash = UINT64_C({metricHash}); |
| {eventName}& Set{metricName}(int64_t value); |
| """.format(eventName=eventInfo.name, |
| metricName=metricInfo.name, |
| metricHash=metricInfo.hash), builders_header_output) |
| |
| builders_impl_output = BUILDERS_IMPL_TEMPLATE._StampFileCode(relpath, data) |
| self.assertIsNotNone(builders_impl_output) |
| self.assertIn("// Generated from gen_builders.py. DO NOT EDIT!", |
| builders_impl_output) |
| self.assertIn("namespace builders", builders_impl_output) |
| self.assertIn( |
| """ |
| const char {name}::kEntryName[] = "{rawName}"; |
| const uint64_t {name}::kEntryNameHash; |
| |
| {name}::{name}(ukm::SourceId source_id) : |
| ::ukm::internal::UkmEntryBuilderBase(source_id, kEntryNameHash) {{ |
| }} |
| |
| {name}::{name}(ukm::SourceIdObj source_id) : |
| ::ukm::internal::UkmEntryBuilderBase(source_id, kEntryNameHash) {{ |
| }}""".format(name=eventInfo.name, rawName=eventInfo.raw_name), |
| builders_impl_output) |
| |
| self.assertIn( |
| """ |
| const char {eventName}::k{metricName}Name[] = "{metricRawName}"; |
| const uint64_t {eventName}::k{metricName}NameHash; |
| |
| {eventName}& {eventName}::Set{metricName}(int64_t value) {{ |
| SetMetricInternal(k{metricName}NameHash, value); |
| return *this; |
| }} |
| """.format(eventName=eventInfo.name, |
| metricName=metricInfo.name, |
| metricRawName=metricInfo.raw_name), builders_impl_output) |
| |
| decode_header_output = DECODE_HEADER_TEMPLATE._StampFileCode(relpath, data) |
| self.assertIsNotNone(decode_header_output) |
| self.assertIn("// Generated from gen_builders.py. DO NOT EDIT!", |
| decode_header_output) |
| self.assertIn("namespace builders", decode_header_output) |
| self.assertIn( |
| """typedef std::map<uint64_t, const char*> MetricDecodeMap; |
| struct EntryDecoder { |
| const char* name; |
| const MetricDecodeMap metric_map; |
| }; |
| typedef std::map<uint64_t, EntryDecoder> DecodeMap; |
| DecodeMap CreateDecodeMap();""", decode_header_output) |
| |
| decode_impl_output = DECODE_IMPL_TEMPLATE._StampFileCode(relpath, data) |
| self.assertIsNotNone(decode_impl_output) |
| self.assertIn("// Generated from gen_builders.py. DO NOT EDIT!", |
| decode_impl_output) |
| self.assertIn("namespace builders", decode_impl_output) |
| self.assertIn( |
| """ |
| {{{eventName}::k{metricName}NameHash, {eventName}::k{metricName}Name}},""" |
| .format(eventName=eventInfo.name, |
| metricName=metricInfo.name), decode_impl_output) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |