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

# Integration tests for remote_link.
#
# Usage:
#
# Ensure that gomacc or rewrapper, llvm-objdump, and llvm-dwarfdump are in your
# PATH.
# Then run:
#
#   tools/clang/scripts/remote_link_integration_tests.py
#
# See also remote_link_unit_tests.py, which contains unit tests and
# instructions for generating coverage information.

import remote_ld
import remote_link

from io import StringIO
import os
import re
import shlex
import subprocess
import unittest
from unittest import mock

from remote_link_test_utils import named_directory, working_directory

# Path constants.
CHROMIUM_DIR = os.path.abspath(
    os.path.join(os.path.dirname(__file__), '..', '..', '..'))
LLVM_BIN_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build',
                            'Release+Asserts', 'bin')


def _create_inputs(path):
  """
  Creates input files under path.
  """
  with open(os.path.join(path, 'main.cpp'), 'w') as f:
    f.write('extern int foo();\n'
            'int main(int argc, char *argv[]) {\n  return foo();\n}\n')
  with open(os.path.join(path, 'foo.cpp'), 'w') as f:
    f.write('int foo() {\n  return 12;\n}\n')
  with open(os.path.join(path, 'bar.cpp'), 'w') as f:
    f.write('int bar() {\n  return 9;\n}\n')


def _lto_args(generate_bitcode):
  """
  Returns list of arguments to clang to generate bitcode or not.
  """
  if generate_bitcode:
    return ['-flto=thin']
  else:
    return []


class RemoteLinkUnixAllowMain(remote_ld.RemoteLinkUnix):
  """
  Same as remote_ld.RemoteLinkUnix, but has "main" on the allow list.
  """

  def __init__(self, *args, **kwargs):
    super(RemoteLinkUnixAllowMain, self).__init__(*args, **kwargs)
    self.ALLOWLIST = {'main'}


class RemoteLinkWindowsAllowMain(remote_link.RemoteLinkWindows):
  """
  Same as remote_ld.RemoteLinkWindows, but has "main" on the allow list.
  """

  def __init__(self, *args, **kwargs):
    super(RemoteLinkWindowsAllowMain, self).__init__(*args, **kwargs)
    self.ALLOWLIST = {'main.exe'}


class RemoteLinkIntegrationTest(unittest.TestCase):
  def clangcl(self):
    return os.path.join(LLVM_BIN_DIR, 'clang-cl' + remote_link.exe_suffix())

  def lld_link(self):
    return os.path.join(LLVM_BIN_DIR, 'lld-link' + remote_link.exe_suffix())

  def llvmar(self):
    return os.path.join(LLVM_BIN_DIR, 'llvm-ar' + remote_link.exe_suffix())

  def test_distributed_lto_common_objs(self):
    with named_directory() as d, working_directory(d):
      _create_inputs(d)
      os.makedirs('obj')
      subprocess.check_call([
          self.clangcl(), '-c', '-Os', '-flto=thin', 'main.cpp',
          '-Foobj/main.obj'
      ])
      subprocess.check_call([
          self.clangcl(), '-c', '-Os', '-flto=thin', 'foo.cpp', '-Foobj/foo.obj'
      ])
      subprocess.check_call([
          self.clangcl(), '-c', '-Os', '-flto=thin', 'bar.cpp', '-Foobj/bar.obj'
      ])
      subprocess.check_call([
          self.llvmar(), 'crsT', 'obj/foobar.lib', 'obj/bar.obj', 'obj/foo.obj'
      ])
      with open('main.rsp', 'w') as f:
        f.write('obj/main.obj\n' 'obj/foobar.lib\n')
      with open('my_goma.sh', 'w') as f:
        f.write('#! /bin/sh\n\ngomacc "$@"\n')
      os.chmod('my_goma.sh', 0o755)
      rc = remote_link.RemoteLinkWindows().main([
          'remote_link.py', '--wrapper', './my_goma.sh', '--ar-path',
          self.llvmar(), '--',
          self.lld_link(), '-nodefaultlib', '-entry:main', '-out:main.exe',
          '@main.rsp'
      ])
      # Should succeed.
      self.assertEqual(rc, 0)
      # Check codegen parameters.
      with open(os.path.join(d, 'lto.main.exe', 'build.ninja')) as f:
        buildrules = f.read()
        codegen_match = re.search('^rule codegen\\b.*?^[^ ]', buildrules,
                                  re.MULTILINE | re.DOTALL)
        self.assertIsNotNone(codegen_match)
        codegen_text = codegen_match.group(0)
        self.assertIn('my_goma.sh', codegen_text)
        self.assertNotIn('-flto', codegen_text)
        self.assertIn('build common_objs/obj/main.obj.stamp : codegen ',
                      buildrules)
        self.assertIn('build common_objs/obj/foo.obj.stamp : codegen ',
                      buildrules)
        self.assertIn(' index = common_objs/empty.thinlto.bc', buildrules)
        link_match = re.search('^build main.exe : native-link\\b.*?^[^ ]',
                               buildrules, re.MULTILINE | re.DOTALL)
        self.assertIsNotNone(link_match)
        link_text = link_match.group(0)
        self.assertNotIn('main.exe.split.obj', link_text)
      # Check that main does not call foo.
      disasm = subprocess.check_output(['llvm-objdump', '-d', 'main.exe'])
      # There are no symbols in the disassembly, but we're expecting two
      # functions, one of which calls the other.
      self.assertTrue(b'call' in disasm or b'jmp' in disasm)

  def test_distributed_lto_allowlist(self):
    with named_directory() as d, working_directory(d):
      _create_inputs(d)
      os.makedirs('obj')
      subprocess.check_call([
          self.clangcl(), '-c', '-Os', '-flto=thin', '-m32', 'main.cpp',
          '-Foobj/main.obj'
      ])
      subprocess.check_call([
          self.clangcl(), '-c', '-Os', '-flto=thin', '-m32', 'foo.cpp',
          '-Foobj/foo.obj'
      ])
      subprocess.check_call([
          self.clangcl(), '-c', '-Os', '-flto=thin', '-m32', 'bar.cpp',
          '-Foobj/bar.obj'
      ])
      subprocess.check_call([
          self.llvmar(), 'crsT', 'obj/foobar.lib', 'obj/bar.obj', 'obj/foo.obj'
      ])
      with open('main.rsp', 'w') as f:
        f.write('obj/main.obj\n' 'obj/foobar.lib\n')
      rc = RemoteLinkWindowsAllowMain().main([
          'remote_link.py', '--wrapper', 'gomacc', '--ar-path',
          self.llvmar(), '--',
          self.lld_link(), '-nodefaultlib', '-entry:main', '-machine:X86',
          '-opt:lldlto=2', '-mllvm:-import-instr-limit=10', '-out:main.exe',
          '@main.rsp'
      ])
      # Should succeed.
      self.assertEqual(rc, 0)
      # Check codegen parameters.
      with open(os.path.join(d, 'lto.main.exe', 'build.ninja')) as f:
        buildrules = f.read()
        codegen_match = re.search('^rule codegen\\b.*?^[^ ]', buildrules,
                                  re.MULTILINE | re.DOTALL)
        self.assertIsNotNone(codegen_match)
        codegen_text = codegen_match.group(0)
        self.assertIn('gomacc', codegen_text)
        self.assertIn('-m32', codegen_text)
        self.assertIn('-mllvm -import-instr-limit=10', codegen_text)
        self.assertNotIn('-flto', codegen_text)
        self.assertIn('build lto.main.exe/obj/main.obj.stamp : codegen ',
                      buildrules)
        self.assertIn('build lto.main.exe/obj/foo.obj.stamp : codegen ',
                      buildrules)
        link_match = re.search('^build main.exe : native-link\\b.*?^[^ ]',
                               buildrules, re.MULTILINE | re.DOTALL)
        self.assertIsNotNone(link_match)
        link_text = link_match.group(0)
        self.assertIn('main.exe.split.obj', link_text)
      # Check that main does not call foo.
      disasm = subprocess.check_output(['llvm-objdump', '-d', 'main.exe'])
      # There are no symbols in the disassembly, but we're expecting a single
      # function, with no calls or jmps.
      self.assertNotIn(b'jmp', disasm)
      self.assertNotIn(b'call', disasm)

  def test_override_allowlist(self):
    with named_directory() as d, working_directory(d):
      _create_inputs(d)
      os.makedirs('obj')
      subprocess.check_call([
          self.clangcl(), '-c', '-O2', '-flto=thin', 'main.cpp',
          '-Foobj/main.obj'
      ])
      subprocess.check_call([
          self.clangcl(), '-c', '-O2', '-flto=thin', 'foo.cpp', '-Foobj/foo.obj'
      ])
      rc = remote_link.RemoteLinkWindows().main([
          'remote_link.py', '--generate', '--allowlist', '--ar-path',
          self.llvmar(), '--',
          self.lld_link(), '-nodefaultlib', '-entry:main', '-opt:lldlto=2',
          '-out:main.exe', 'obj/main.obj', 'obj/foo.obj'
      ])
      # Should succeed.
      self.assertEqual(rc, 0)
      # Check that we have rules for main and foo, and that they are
      # not common objects.
      with open(os.path.join(d, 'lto.main.exe', 'build.ninja')) as f:
        buildrules = f.read()
        codegen_match = re.search(r'^rule codegen\b.*?^[^ ]', buildrules,
                                  re.MULTILINE | re.DOTALL)
        self.assertIsNotNone(codegen_match)
        codegen_text = codegen_match.group(0)
        self.assertNotIn('-flto', codegen_text)
        self.assertIn('build lto.main.exe/obj/main.obj.stamp : codegen ',
                      buildrules)
        self.assertIn('build lto.main.exe/obj/foo.obj.stamp : codegen ',
                      buildrules)
        link_match = re.search(r'^build main.exe : native-link\b.*?^[^ ]',
                               buildrules, re.MULTILINE | re.DOTALL)
        self.assertIsNotNone(link_match)


class RemoteLdIntegrationTest(unittest.TestCase):
  def clangxx(self):
    return os.path.join(LLVM_BIN_DIR, 'clang++' + remote_link.exe_suffix())

  def llvmar(self):
    return os.path.join(LLVM_BIN_DIR, 'llvm-ar' + remote_link.exe_suffix())

  def test_nonlto(self):
    with named_directory() as d, working_directory(d):
      _create_inputs(d)
      subprocess.check_call(
          [self.clangxx(), '-c', '-Os', 'main.cpp', '-o', 'main.o'])
      subprocess.check_call(
          [self.clangxx(), '-c', '-Os', 'foo.cpp', '-o', 'foo.o'])
      rc = RemoteLinkUnixAllowMain().main([
          'remote_ld.py', '--wrapper', 'gomacc', '--ar-path',
          self.llvmar(), '--',
          self.clangxx(), '-fuse-ld=lld', 'main.o', 'foo.o', '-o', 'main'
      ])
      # Should succeed.
      self.assertEqual(rc, 0)
      # lto.main directory should not be present.
      self.assertFalse(os.path.exists(os.path.join(d, 'lto.main')))
      # Check that main calls foo.
      disasm = subprocess.check_output(['llvm-objdump', '-d', 'main'])
      main_idx = disasm.index(b' <main>:\n')
      after_main_idx = disasm.index(b'\n\n', main_idx)
      main_disasm = disasm[main_idx:after_main_idx]
      self.assertIn(b'foo', main_disasm)

  def test_fallback_lto(self):
    with named_directory() as d, working_directory(d):
      _create_inputs(d)
      subprocess.check_call([
          self.clangxx(), '-c', '-Os', '-flto=thin', 'main.cpp', '-o', 'main.o'
      ])
      subprocess.check_call(
          [self.clangxx(), '-c', '-Os', '-flto=thin', 'foo.cpp', '-o', 'foo.o'])
      rc = remote_ld.RemoteLinkUnix().main([
          'remote_ld.py', '--wrapper', 'gomacc', '--ar-path',
          self.llvmar(), '--',
          self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'main.o', 'foo.o', '-o',
          'main'
      ])
      # Should succeed.
      self.assertEqual(rc, 0)
      # lto.main directory should not be present.
      self.assertFalse(os.path.exists(os.path.join(d, 'lto.main')))
      # Check that main does not call foo.
      disasm = subprocess.check_output(['llvm-objdump', '-d', 'main'])
      main_idx = disasm.index(b' <main>:\n')
      after_main_idx = disasm.index(b'\n\n', main_idx)
      main_disasm = disasm[main_idx:after_main_idx]
      self.assertNotIn(b'foo', main_disasm)

  def test_distributed_lto(self):
    with named_directory() as d, working_directory(d):
      _create_inputs(d)
      subprocess.check_call([
          self.clangxx(), '-c', '-Os', '-flto=thin', 'main.cpp', '-o', 'main.o'
      ])
      subprocess.check_call(
          [self.clangxx(), '-c', '-Os', '-flto=thin', 'foo.cpp', '-o', 'foo.o'])
      rc = RemoteLinkUnixAllowMain().main([
          'remote_ld.py', '-j', '16', '--ar-path',
          self.llvmar(), '--',
          self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'main.o', 'foo.o', '-o',
          'main'
      ])
      # Should succeed.
      self.assertEqual(rc, 0)
      # build.ninja file should have gomacc invocations in it.
      with open(os.path.join(d, 'lto.main', 'build.ninja')) as f:
        buildrules = f.read()
        self.assertIn('gomacc ', buildrules)
        self.assertIn('build lto.main/main.o.stamp : codegen ', buildrules)
        self.assertIn('build lto.main/foo.o.stamp : codegen ', buildrules)
      # Check that main does not call foo.
      disasm = subprocess.check_output(['llvm-objdump', '-d', 'main'])
      main_idx = disasm.index(b' <main>:\n')
      after_main_idx = disasm.index(b'\n\n', main_idx)
      main_disasm = disasm[main_idx:after_main_idx]
      self.assertNotIn(b'foo', main_disasm)

  def test_distributed_lto_thin_archive_same_dir(self):
    with named_directory() as d, working_directory(d):
      _create_inputs(d)
      subprocess.check_call([
          self.clangxx(), '-c', '-Os', '-flto=thin', 'main.cpp', '-o', 'main.o'
      ])
      subprocess.check_call(
          [self.clangxx(), '-c', '-Os', '-flto=thin', 'foo.cpp', '-o', 'foo.o'])
      subprocess.check_call(
          [self.clangxx(), '-c', '-Os', '-flto=thin', 'bar.cpp', '-o', 'bar.o'])
      subprocess.check_call(
          [self.llvmar(), 'crsT', 'libfoobar.a', 'bar.o', 'foo.o'])
      rc = RemoteLinkUnixAllowMain().main([
          'remote_ld.py', '--ar-path',
          self.llvmar(), '--',
          self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'main.o', 'libfoobar.a',
          '-o', 'main'
      ])
      # Should succeed.
      self.assertEqual(rc, 0)
      # build.ninja file should have gomacc invocations in it.
      with open(os.path.join(d, 'lto.main', 'build.ninja')) as f:
        buildrules = f.read()
        self.assertIn('gomacc ', buildrules)
        self.assertIn('build lto.main/main.o.stamp : codegen ', buildrules)
        self.assertIn('build lto.main/foo.o.stamp : codegen ', buildrules)
      # Check that main does not call foo.
      disasm = subprocess.check_output(['llvm-objdump', '-d', 'main'])
      main_idx = disasm.index(b' <main>:\n')
      after_main_idx = disasm.index(b'\n\n', main_idx)
      main_disasm = disasm[main_idx:after_main_idx]
      self.assertNotIn(b'foo', main_disasm)

  def test_distributed_lto_thin_archive_subdir(self):
    self.run_archive_test(bitcode_archive=True,
                          bitcode_main=True,
                          thin_archive=True)

  def test_distributed_machine_code_thin_archive_bitcode_main_subdir(self):
    self.run_archive_test(bitcode_archive=False,
                          bitcode_main=True,
                          thin_archive=True)

  def test_distributed_machine_code_thin_archive_subdir(self):
    self.run_archive_test(bitcode_archive=False,
                          bitcode_main=False,
                          thin_archive=True)

  def test_distributed_bitcode_thick_archive_subdir(self):
    self.run_archive_test(bitcode_archive=True,
                          bitcode_main=True,
                          thin_archive=False)

  def test_distributed_machine_code_thick_archive_subdir(self):
    self.run_archive_test(bitcode_archive=False,
                          bitcode_main=False,
                          thin_archive=False)

  def test_distributed_machine_code_thick_archive_bitcode_main_subdir(self):
    self.run_archive_test(bitcode_archive=False,
                          bitcode_main=True,
                          thin_archive=False)

  def run_archive_test(self, bitcode_archive, bitcode_main, thin_archive):
    """
    Runs a test to ensure correct remote linking handling of
    an archive.
    Arguments:
    bitcode_archive: whether the archive should contain bitcode (true)
    or machine code (false)
    bitcode_main: whether the main object, outside the archive, should
    contain bitcode (true) or machine code (false)
    thin_archive: whether to create a thin archive instead of a regular archive.
    """
    with named_directory() as d, working_directory(d):
      _create_inputs(d)
      os.makedirs('obj')
      subprocess.check_call(
          [self.clangxx(), '-c', '-Os', 'main.cpp', '-o', 'obj/main.o'] +
          _lto_args(bitcode_main))
      subprocess.check_call(
          [self.clangxx(), '-c', '-Os', 'foo.cpp', '-o', 'obj/foo.o'] +
          _lto_args(bitcode_archive))
      subprocess.check_call(
          [self.clangxx(), '-c', '-Os', 'bar.cpp', '-o', 'obj/bar.o'] +
          _lto_args(bitcode_archive))
      archive_creation_arg = 'crs'
      if thin_archive:
        archive_creation_arg = 'crsT'
      subprocess.check_call([
          self.llvmar(), archive_creation_arg, 'obj/libfoobar.a', 'obj/bar.o',
          'obj/foo.o'
      ])
      rc = RemoteLinkUnixAllowMain().main([
          'remote_ld.py', '--ar-path',
          self.llvmar(), '--',
          self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'obj/main.o',
          'obj/libfoobar.a', '-o', 'main'
      ])
      # Should succeed.
      self.assertEqual(rc, 0)
      if bitcode_main or bitcode_archive:
        # build.ninja file should have gomacc invocations in it.
        with open(os.path.join(d, 'lto.main', 'build.ninja')) as f:
          buildrules = f.read()
          self.assertIn('gomacc ', buildrules)
          if bitcode_main:
            self.assertIn('build lto.main/obj/main.o.stamp : codegen ',
                          buildrules)
          if bitcode_archive:
            if thin_archive:
              self.assertIn('build lto.main/obj/foo.o.stamp : codegen ',
                            buildrules)
            else:
              self.assertIn(
                  'build lto.main/expanded_archives/obj/libfoobar.a/' +
                  'foo.o.stamp : codegen ', buildrules)
      # Check that main does not call foo.
      if bitcode_archive:
        disasm = subprocess.check_output(['llvm-objdump', '-d', 'main'])
        main_idx = disasm.index(b' <main>:\n')
        after_main_idx = disasm.index(b'\n\n', main_idx)
        main_disasm = disasm[main_idx:after_main_idx]
        self.assertNotIn(b'foo', main_disasm)

  def test_debug_params(self):
    with named_directory() as d, working_directory(d):
      _create_inputs(d)
      os.makedirs('obj')
      subprocess.check_call([
          self.clangxx(), '-c', '-g', '-gsplit-dwarf', '-flto=thin', 'main.cpp',
          '-o', 'obj/main.o'
      ])
      subprocess.check_call([
          self.clangxx(), '-c', '-g', '-gsplit-dwarf', '-flto=thin', 'foo.cpp',
          '-o', 'obj/foo.o'
      ])
      with open('main.rsp', 'w') as f:
        f.write('obj/main.o\n' 'obj/foo.o\n')
      rc = RemoteLinkUnixAllowMain().main([
          'remote_ld.py', '--ar-path',
          self.llvmar(), '--',
          self.clangxx(), '-fuse-ld=lld', '-flto=thin', '-g', '-gsplit-dwarf',
          '-Wl,--lto-O2', '-o', 'main', '@main.rsp'
      ])
      # Should succeed.
      self.assertEqual(rc, 0)
      # Check debug info present, refers to .dwo file, and does not
      # contain full debug info for foo.cpp.
      dbginfo = subprocess.check_output(
          ['llvm-dwarfdump', '-debug-info',
           'main']).decode('utf-8', 'backslashreplace')
      self.assertRegexpMatches(dbginfo, '\\bDW_AT_GNU_dwo_name\\b.*\\.dwo"')
      self.assertNotRegexpMatches(dbginfo, '\\bDW_AT_name\\b.*foo\\.cpp"')

  def test_distributed_lto_params(self):
    with named_directory() as d, working_directory(d):
      _create_inputs(d)
      os.makedirs('obj')
      subprocess.check_call([
          self.clangxx(), '-c', '-Os', '-flto=thin', '-m32', '-fsplit-lto-unit',
          '-fwhole-program-vtables', 'main.cpp', '-o', 'obj/main.o'
      ])
      subprocess.check_call([
          self.clangxx(), '-c', '-Os', '-flto=thin', '-m32', '-fsplit-lto-unit',
          '-fwhole-program-vtables', 'foo.cpp', '-o', 'obj/foo.o'
      ])
      subprocess.check_call([
          self.clangxx(), '-c', '-Os', '-flto=thin', '-m32', '-fsplit-lto-unit',
          '-fwhole-program-vtables', 'bar.cpp', '-o', 'obj/bar.o'
      ])
      subprocess.check_call(
          [self.llvmar(), 'crsT', 'obj/libfoobar.a', 'obj/bar.o', 'obj/foo.o'])
      with open('main.rsp', 'w') as f:
        f.write('-fsplit-lto-unit\n'
                '-fwhole-program-vtables\n'
                'obj/main.o\n'
                'obj/libfoobar.a\n')
      rc = RemoteLinkUnixAllowMain().main([
          'remote_ld.py', '--ar-path',
          self.llvmar(), '--',
          self.clangxx(), '-fuse-ld=lld', '-flto=thin', '-m32', '-Wl,-mllvm',
          '-Wl,-generate-type-units', '-Wl,--lto-O2', '-o', 'main',
          '-Wl,--start-group', '@main.rsp', '-Wl,--end-group'
      ])
      # Should succeed.
      self.assertEqual(rc, 0)
      # Check codegen parameters.
      with open(os.path.join(d, 'lto.main', 'build.ninja')) as f:
        buildrules = f.read()
        codegen_match = re.search('^rule codegen\\b.*?^[^ ]', buildrules,
                                  re.MULTILINE | re.DOTALL)
        self.assertIsNotNone(codegen_match)
        codegen_text = codegen_match.group(0)
        self.assertIn('gomacc', codegen_text)
        self.assertIn('-m32', codegen_text)
        self.assertIn('-mllvm -generate-type-units', codegen_text)
        self.assertNotIn('-flto', codegen_text)
        self.assertIn('build lto.main/obj/main.o.stamp : codegen ', buildrules)
        self.assertIn('build lto.main/obj/foo.o.stamp : codegen ', buildrules)
        link_match = re.search('^build main : native-link\\b.*?^[^ ]',
                               buildrules, re.MULTILINE | re.DOTALL)
        self.assertIsNotNone(link_match)
        link_text = link_match.group(0)
        self.assertIn('main.split.o', link_text)
      # Check that main does not call foo.
      disasm = subprocess.check_output(['llvm-objdump', '-d', 'main'])
      main_idx = disasm.index(b' <main>:\n')
      after_main_idx = disasm.index(b'\n\n', main_idx)
      main_disasm = disasm[main_idx:after_main_idx]
      self.assertNotIn(b'foo', main_disasm)

  def test_no_gomacc(self):
    with named_directory() as d, working_directory(d):
      _create_inputs(d)
      subprocess.check_call([
          self.clangxx(), '-c', '-Os', '-flto=thin', 'main.cpp', '-o', 'main.o'
      ])
      subprocess.check_call(
          [self.clangxx(), '-c', '-Os', '-flto=thin', 'foo.cpp', '-o', 'foo.o'])
      rc = RemoteLinkUnixAllowMain().main([
          'remote_ld.py', '--ar-path',
          self.llvmar(), '--no-wrapper', '-j', '16', '--',
          self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'main.o', 'foo.o', '-o',
          'main'
      ])
      # Should succeed.
      self.assertEqual(rc, 0)
      # build.ninja file should not have gomacc invocations in it.
      with open(os.path.join(d, 'lto.main', 'build.ninja')) as f:
        buildrules = f.read()
        self.assertNotIn('gomacc ', buildrules)
        self.assertIn('build lto.main/main.o.stamp : codegen ', buildrules)
        self.assertIn('build lto.main/foo.o.stamp : codegen ', buildrules)
      # Check that main does not call foo.
      disasm = subprocess.check_output(['llvm-objdump', '-d', 'main'])
      main_idx = disasm.index(b' <main>:\n')
      after_main_idx = disasm.index(b'\n\n', main_idx)
      main_disasm = disasm[main_idx:after_main_idx]
      self.assertNotIn(b'foo', main_disasm)

  def test_generate_no_codegen(self):
    with named_directory() as d, working_directory(d):
      with open('main.o', 'wb') as f:
        f.write(b'\7fELF')
      with mock.patch('sys.stderr', new_callable=StringIO) as stderr:
        rc = RemoteLinkUnixAllowMain().main([
            'remote_ld.py', '--ar-path',
            self.llvmar(), '--generate', '--',
            self.clangxx(), 'main.o', '-o', 'main'
        ])
        self.assertEqual(rc, 5)
        self.assertIn('no ninja file generated.\n', stderr.getvalue())

  def test_generate(self):
    with named_directory() as d, working_directory(d):
      with open('main.o', 'wb') as f:
        f.write(b'BC\xc0\xde')
      with mock.patch('sys.stderr', new_callable=StringIO) as stderr:
        rc = RemoteLinkUnixAllowMain().main([
            'remote_ld.py', '--ar-path',
            self.llvmar(), '--generate', '--',
            self.clangxx(), 'main.o', '-o', 'main'
        ])
        self.assertEqual(rc, 0)
        m = re.search('ninja file (.*)', stderr.getvalue())
        self.assertIsNotNone(m)
        path = shlex.split(m.group(1))[0]
        self.assertTrue(os.path.exists(path))
        content = open(path).read()
        self.assertRegex(
            content,
            re.compile('^build [^:]+/main\\.o\\.stamp : codegen ',
                       re.MULTILINE))

  def test_override_allowlist(self):
    with named_directory() as d, working_directory(d):
      _create_inputs(d)
      subprocess.check_call([
          self.clangxx(), '-c', '-Os', '-flto=thin', 'main.cpp', '-o', 'main.o'
      ])
      subprocess.check_call(
          [self.clangxx(), '-c', '-Os', '-flto=thin', 'foo.cpp', '-o', 'foo.o'])
      rc = remote_ld.RemoteLinkUnix().main([
          'remote_ld.py', '--ar-path',
          self.llvmar(), '--generate', '--allowlist', '--',
          self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'main.o', 'foo.o', '-o',
          'main'
      ])
      # Should succeed.
      self.assertEqual(rc, 0)
      # build.ninja file should have rules for main and foo.
      ninjafile = os.path.join(d, 'lto.main', 'build.ninja')
      self.assertTrue(os.path.exists(ninjafile))
      with open(ninjafile) as f:
        buildrules = f.read()
        self.assertIn('build lto.main/main.o.stamp : codegen ', buildrules)
        self.assertIn('build lto.main/foo.o.stamp : codegen ', buildrules)


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