1*333d2b36SAndroid Build Coastguard Worker#!/usr/bin/env python 2*333d2b36SAndroid Build Coastguard Worker# 3*333d2b36SAndroid Build Coastguard Worker# Copyright (C) 2023 The Android Open Source Project 4*333d2b36SAndroid Build Coastguard Worker# 5*333d2b36SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*333d2b36SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*333d2b36SAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*333d2b36SAndroid Build Coastguard Worker# 9*333d2b36SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*333d2b36SAndroid Build Coastguard Worker# 11*333d2b36SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*333d2b36SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*333d2b36SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*333d2b36SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*333d2b36SAndroid Build Coastguard Worker# limitations under the License. 16*333d2b36SAndroid Build Coastguard Worker# 17*333d2b36SAndroid Build Coastguard Worker"""Unit tests for conv_linker_config.py.""" 18*333d2b36SAndroid Build Coastguard Worker 19*333d2b36SAndroid Build Coastguard Workerimport io 20*333d2b36SAndroid Build Coastguard Workerimport os 21*333d2b36SAndroid Build Coastguard Workerimport shutil 22*333d2b36SAndroid Build Coastguard Workerimport tempfile 23*333d2b36SAndroid Build Coastguard Workerimport unittest 24*333d2b36SAndroid Build Coastguard Worker 25*333d2b36SAndroid Build Coastguard Workerimport conv_linker_config 26*333d2b36SAndroid Build Coastguard Workerfrom contextlib import redirect_stderr 27*333d2b36SAndroid Build Coastguard Workerfrom linker_config_pb2 import LinkerConfig 28*333d2b36SAndroid Build Coastguard Worker 29*333d2b36SAndroid Build Coastguard Workerclass FileArgs: 30*333d2b36SAndroid Build Coastguard Worker def __init__(self, files, sep = ':'): 31*333d2b36SAndroid Build Coastguard Worker self.files = files 32*333d2b36SAndroid Build Coastguard Worker self.sep = sep 33*333d2b36SAndroid Build Coastguard Worker 34*333d2b36SAndroid Build Coastguard Worker 35*333d2b36SAndroid Build Coastguard Workerclass FileArg: 36*333d2b36SAndroid Build Coastguard Worker def __init__(self, file): 37*333d2b36SAndroid Build Coastguard Worker self.file = file 38*333d2b36SAndroid Build Coastguard Worker 39*333d2b36SAndroid Build Coastguard Worker 40*333d2b36SAndroid Build Coastguard Workerclass TempDirTest(unittest.TestCase): 41*333d2b36SAndroid Build Coastguard Worker 42*333d2b36SAndroid Build Coastguard Worker def setUp(self): 43*333d2b36SAndroid Build Coastguard Worker self.tempdir = tempfile.mkdtemp() 44*333d2b36SAndroid Build Coastguard Worker 45*333d2b36SAndroid Build Coastguard Worker 46*333d2b36SAndroid Build Coastguard Worker def tearDown(self): 47*333d2b36SAndroid Build Coastguard Worker shutil.rmtree(self.tempdir) 48*333d2b36SAndroid Build Coastguard Worker 49*333d2b36SAndroid Build Coastguard Worker 50*333d2b36SAndroid Build Coastguard Worker def write(self, name, contents): 51*333d2b36SAndroid Build Coastguard Worker with open(os.path.join(self.tempdir, name), 'wb') as f: 52*333d2b36SAndroid Build Coastguard Worker f.write(contents) 53*333d2b36SAndroid Build Coastguard Worker 54*333d2b36SAndroid Build Coastguard Worker 55*333d2b36SAndroid Build Coastguard Worker def read(self, name): 56*333d2b36SAndroid Build Coastguard Worker with open(os.path.join(self.tempdir, name), 'rb') as f: 57*333d2b36SAndroid Build Coastguard Worker return f.read() 58*333d2b36SAndroid Build Coastguard Worker 59*333d2b36SAndroid Build Coastguard Worker 60*333d2b36SAndroid Build Coastguard Worker def resolve_paths(self, args): 61*333d2b36SAndroid Build Coastguard Worker for i in range(len(args)): 62*333d2b36SAndroid Build Coastguard Worker if isinstance(args[i], FileArgs): 63*333d2b36SAndroid Build Coastguard Worker args[i] = args[i].sep.join(os.path.join(self.tempdir, f.file) for f in args[i].files) 64*333d2b36SAndroid Build Coastguard Worker elif isinstance(args[i], FileArg): 65*333d2b36SAndroid Build Coastguard Worker args[i] = os.path.join(self.tempdir, args[i].file) 66*333d2b36SAndroid Build Coastguard Worker return args 67*333d2b36SAndroid Build Coastguard Worker 68*333d2b36SAndroid Build Coastguard Worker 69*333d2b36SAndroid Build Coastguard Workerclass ConvLinkerConfigTest(TempDirTest): 70*333d2b36SAndroid Build Coastguard Worker """Unit tests for conv_linker_config.""" 71*333d2b36SAndroid Build Coastguard Worker 72*333d2b36SAndroid Build Coastguard Worker 73*333d2b36SAndroid Build Coastguard Worker def test_Proto_empty_input(self): 74*333d2b36SAndroid Build Coastguard Worker self.command(['proto', '-s', '-o', FileArg('out.pb')]) 75*333d2b36SAndroid Build Coastguard Worker pb = LinkerConfig() 76*333d2b36SAndroid Build Coastguard Worker pb.ParseFromString(self.read('out.pb')) 77*333d2b36SAndroid Build Coastguard Worker self.assertEqual(pb, LinkerConfig()) 78*333d2b36SAndroid Build Coastguard Worker 79*333d2b36SAndroid Build Coastguard Worker 80*333d2b36SAndroid Build Coastguard Worker def test_Proto_single_input(self): 81*333d2b36SAndroid Build Coastguard Worker self.write('foo.json', b'{ "provideLibs": ["libfoo.so"]}') 82*333d2b36SAndroid Build Coastguard Worker self.command(['proto', '-s', FileArg('foo.json'), '-o', FileArg('out.pb')]) 83*333d2b36SAndroid Build Coastguard Worker pb = LinkerConfig() 84*333d2b36SAndroid Build Coastguard Worker pb.ParseFromString(self.read('out.pb')) 85*333d2b36SAndroid Build Coastguard Worker self.assertSequenceEqual(pb.provideLibs, ['libfoo.so']) 86*333d2b36SAndroid Build Coastguard Worker 87*333d2b36SAndroid Build Coastguard Worker 88*333d2b36SAndroid Build Coastguard Worker def test_Proto_with_multiple_input(self): 89*333d2b36SAndroid Build Coastguard Worker self.write('foo.json', b'{ "provideLibs": ["libfoo.so"]}') 90*333d2b36SAndroid Build Coastguard Worker self.write('bar.json', b'{ "provideLibs": ["libbar.so"]}') 91*333d2b36SAndroid Build Coastguard Worker self.command(['proto', '-s', FileArgs([FileArg('foo.json'), FileArg('bar.json')]), '-o', FileArg('out.pb')]) 92*333d2b36SAndroid Build Coastguard Worker pb = LinkerConfig() 93*333d2b36SAndroid Build Coastguard Worker pb.ParseFromString(self.read('out.pb')) 94*333d2b36SAndroid Build Coastguard Worker self.assertSetEqual(set(pb.provideLibs), set(['libfoo.so', 'libbar.so'])) 95*333d2b36SAndroid Build Coastguard Worker 96*333d2b36SAndroid Build Coastguard Worker 97*333d2b36SAndroid Build Coastguard Worker def test_Proto_with_existing_output(self): 98*333d2b36SAndroid Build Coastguard Worker self.write('out.pb', LinkerConfig(provideLibs=['libfoo.so']).SerializeToString()) 99*333d2b36SAndroid Build Coastguard Worker buf = io.StringIO() 100*333d2b36SAndroid Build Coastguard Worker with self.assertRaises(SystemExit) as err: 101*333d2b36SAndroid Build Coastguard Worker with redirect_stderr(buf): 102*333d2b36SAndroid Build Coastguard Worker self.command(['proto', '-o', FileArg('out.pb')]) 103*333d2b36SAndroid Build Coastguard Worker self.assertEqual(err.exception.code, 1) 104*333d2b36SAndroid Build Coastguard Worker self.assertRegex(buf.getvalue(), r'.*out\.pb exists') 105*333d2b36SAndroid Build Coastguard Worker 106*333d2b36SAndroid Build Coastguard Worker 107*333d2b36SAndroid Build Coastguard Worker def test_Proto_with_append(self): 108*333d2b36SAndroid Build Coastguard Worker self.write('out.pb', LinkerConfig(provideLibs=['libfoo.so']).SerializeToString()) 109*333d2b36SAndroid Build Coastguard Worker self.write('bar.json', b'{ "provideLibs": ["libbar.so"]}') 110*333d2b36SAndroid Build Coastguard Worker self.command(['proto', '-s', FileArg('bar.json'), '-o', FileArg('out.pb'), '-a']) 111*333d2b36SAndroid Build Coastguard Worker pb = LinkerConfig() 112*333d2b36SAndroid Build Coastguard Worker pb.ParseFromString(self.read('out.pb')) 113*333d2b36SAndroid Build Coastguard Worker self.assertSetEqual(set(pb.provideLibs), set(['libfoo.so', 'libbar.so'])) 114*333d2b36SAndroid Build Coastguard Worker 115*333d2b36SAndroid Build Coastguard Worker 116*333d2b36SAndroid Build Coastguard Worker def test_Proto_with_force(self): 117*333d2b36SAndroid Build Coastguard Worker self.write('out.pb', LinkerConfig(provideLibs=['libfoo.so']).SerializeToString()) 118*333d2b36SAndroid Build Coastguard Worker self.write('bar.json', b'{ "provideLibs": ["libbar.so"]}') 119*333d2b36SAndroid Build Coastguard Worker self.command(['proto', '-s', FileArg('bar.json'), '-o', FileArg('out.pb'), '-f']) 120*333d2b36SAndroid Build Coastguard Worker pb = LinkerConfig() 121*333d2b36SAndroid Build Coastguard Worker pb.ParseFromString(self.read('out.pb')) 122*333d2b36SAndroid Build Coastguard Worker self.assertSetEqual(set(pb.provideLibs), set(['libbar.so'])) 123*333d2b36SAndroid Build Coastguard Worker 124*333d2b36SAndroid Build Coastguard Worker 125*333d2b36SAndroid Build Coastguard Worker def command(self, args): 126*333d2b36SAndroid Build Coastguard Worker parser = conv_linker_config.GetArgParser() 127*333d2b36SAndroid Build Coastguard Worker parsed_args = parser.parse_args(self.resolve_paths(args)) 128*333d2b36SAndroid Build Coastguard Worker parsed_args.func(parsed_args) 129*333d2b36SAndroid Build Coastguard Worker 130*333d2b36SAndroid Build Coastguard Worker 131*333d2b36SAndroid Build Coastguard Workerif __name__ == '__main__': 132*333d2b36SAndroid Build Coastguard Worker unittest.main(verbosity=2) 133