1#!/usr/bin/env python 2# 3# Copyright (C) 2019 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17"""Unit tests for process_compat_config.py.""" 18 19import difflib 20import io 21from StringIO import StringIO 22import unittest 23import xml.dom.minidom 24from inspect import currentframe, getframeinfo 25 26import process_compat_config 27 28def here(): 29 f = currentframe().f_back 30 return "%s:%d" % (getframeinfo(f).filename, f.f_lineno) 31 32class ProcessCompatConfigTest(unittest.TestCase): 33 34 def setUp(self): 35 self.merger = process_compat_config.ConfigMerger(detect_conflicts = True) 36 self.stderr = StringIO() 37 self.merger.write_errors_to = self.stderr 38 self.xml = io.BytesIO() 39 40 def assert_same_xml(self, got, expected): 41 got = xml.dom.minidom.parseString(got).toprettyxml() 42 expected = xml.dom.minidom.parseString(expected).toprettyxml() 43 diffs = [diff for diff in difflib.ndiff(got.split('\n'), expected.split('\n')) if not diff.startswith(" ")] 44 self.assertEqual("", "\n".join(diffs), msg="Got unexpected diffs in XML") 45 46 def test_no_config_to_merge(self): 47 self.merger.write(self.xml) 48 self.assert_same_xml(self.xml.getvalue(), "<config />") 49 50 def test_merge_one_file(self): 51 self.merger.merge(io.BytesIO(b'<config><compat-change id="1234" name="TEST_CHANGE" /></config>'), here()) 52 self.merger.write(self.xml) 53 self.assert_same_xml(self.xml.getvalue(), '<config><compat-change id="1234" name="TEST_CHANGE" /></config>') 54 55 def test_merge_two_files(self): 56 self.merger.merge(io.BytesIO(b'<config><compat-change id="1234" name="TEST_CHANGE" /></config>'), here()) 57 self.merger.merge(io.BytesIO(b'<config><compat-change id="1235" name="TEST_CHANGE2" /></config>'), here()) 58 self.merger.write(self.xml) 59 self.assert_same_xml(self.xml.getvalue(), 60 '<config><compat-change id="1234" name="TEST_CHANGE" /><compat-change id="1235" name="TEST_CHANGE2" /></config>') 61 62 def test_merge_two_files_metadata(self): 63 self.merger.merge(io.BytesIO( 64 b'<config><compat-change id="1234" name="TEST_CHANGE"><meta-data definedIn="some.Class" sourcePosition="some.java:1" />' 65 b'</compat-change></config>'), here()) 66 self.merger.merge(io.BytesIO( 67 b'<config><compat-change id="1235" name="TEST_CHANGE2"><meta-data definedIn="other.Class" sourcePosition="other.java:2" />' 68 b'</compat-change></config>'), here()) 69 self.merger.write(self.xml) 70 self.assert_same_xml(self.xml.getvalue(), b'<config>' 71 b'<compat-change id="1234" name="TEST_CHANGE"><meta-data definedIn="some.Class" sourcePosition="some.java:1" /></compat-change>' 72 b'<compat-change id="1235" name="TEST_CHANGE2"><meta-data definedIn="other.Class" sourcePosition="other.java:2" /></compat-change>' 73 b'</config>') 74 75 def test_write_device_config_metadata_stripped(self): 76 self.merger.merge(io.BytesIO( 77 b'<config><compat-change id="1234" name="TEST_CHANGE"><meta-data definedIn="some.Class" sourcePosition="file.java:1"/>' 78 b'</compat-change></config>'), here()) 79 self.merger.write_device_config(self.xml) 80 self.assert_same_xml(self.xml.getvalue(), b'<config>' 81 b'<compat-change id="1234" name="TEST_CHANGE" />' 82 b'</config>') 83 84 def test_merge_two_files_duplicate_id(self): 85 self.merger.merge(io.BytesIO(b'<config><compat-change id="1234" name="TEST_CHANGE" /></config>'), here()) 86 self.merger.merge(io.BytesIO(b'<config><compat-change id="1234" name="TEST_CHANGE2" /></config>'), here()) 87 self.assertIn(r'ERROR: Duplicate definitions for compat change with ID 1234', self.stderr.getvalue()) 88 with self.assertRaisesRegexp(Exception, ' 1 .*error'): 89 self.merger.write(self.xml) 90 91 def test_merge_two_files_duplicate_name(self): 92 self.merger.merge(io.BytesIO(b'<config><compat-change id="1234" name="TEST_CHANGE" /></config>'), here()) 93 self.merger.merge(io.BytesIO(b'<config><compat-change id="1235" name="TEST_CHANGE" /></config>'), here()) 94 self.assertIn(r'ERROR: Duplicate definitions for compat change with name TEST_CHANGE', self.stderr.getvalue()) 95 with self.assertRaisesRegexp(Exception, ' 1 .*error'): 96 self.merger.write(self.xml) 97 98 def test_merge_two_files_duplicate_id_allow_duplicates(self): 99 self.merger = process_compat_config.ConfigMerger(detect_conflicts = False) 100 self.merger.merge(io.BytesIO(b'<config><compat-change id="1234" name="TEST_CHANGE" /></config>'), here()) 101 self.merger.merge(io.BytesIO(b'<config><compat-change id="1234" name="TEST_CHANGE2" /></config>'), here()) 102 self.merger.write(self.xml) 103 104 def test_merge_two_files_duplicate_name_allow_duplicates(self): 105 self.merger = process_compat_config.ConfigMerger(detect_conflicts = False) 106 self.merger.merge(io.BytesIO(b'<config><compat-change id="1234" name="TEST_CHANGE" /></config>'), here()) 107 self.merger.merge(io.BytesIO(b'<config><compat-change id="1235" name="TEST_CHANGE" /></config>'), here()) 108 self.merger.write(self.xml) 109 110if __name__ == '__main__': 111 unittest.main(verbosity=2)