blob: 491ca643eae1a0dbbf8d3fea526f2a46bfc71ec7 [file]
# Copyright 2017 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import re
import unittest
from src.test.py.bazel import test_base
class ActionTempTest(test_base.TestBase):
"""Test that Bazel sets a TMP/TEMP/TMPDIR envvar for actions."""
def testStandaloneBuildAction(self):
self.AssertTempEnvvarWithSpawnStrategy('standalone')
if not test_base.TestBase.IsWindows():
def testLinuxOrDarwinSandboxedBuildAction(self):
self.AssertTempEnvvarWithSpawnStrategy('sandboxed')
def testProcessWrappedSandboxedBuildAction(self):
self.AssertTempEnvvarWithSpawnStrategy('processwrapper-sandbox')
# Helper methods start here -------------------------------------------------
def AssertTempEnvvarWithSpawnStrategy(self, strategy):
self._CreateWorkspace()
strategies = self._SpawnStrategies()
self.assertIn(strategy, strategies)
outputs = self._BuildRules(strategy)
self.assertEqual(len(outputs), 2)
self._AssertOutputFileContents(outputs['genrule'])
self._AssertOutputFileContents(outputs['skylark'])
def _CreateWorkspace(self, build_flags=None):
if test_base.TestBase.IsWindows():
toolname = 'foo.cmd'
toolsrc = [
'@SETLOCAL ENABLEEXTENSIONS',
'@echo ON',
'if [%TMP%] == [] goto fail',
'if [%TEMP%] == [] goto fail',
'',
'echo foo1 > %TMP%\\foo1.txt',
'echo foo2 > %TEMP%\\foo2.txt',
'type %TMP%\\foo1.txt >> %1',
'type %TEMP%\\foo2.txt >> %1',
'echo bar >> %1',
'set >> %1',
'exit /B 0',
'',
':fail',
'echo inner build failed because TMP or TEMP is null > %1',
'exit /B 1',
]
else:
toolname = 'foo.sh'
toolsrc = [
'#!/bin/bash',
'set -eu',
'if [ -n "${TMPDIR:-}" ]; then',
' sleep 1',
' echo foo > "$TMPDIR/foo.txt"',
' cat "$TMPDIR/foo.txt" > "$1"',
' echo bar >> "$1"',
' env | sort >> "$1"',
'else',
' echo "inner build failed because TMPDIR is null" > "$1"',
'fi',
]
self.ScratchFile('WORKSPACE')
self.ScratchFile('foo/' + toolname, toolsrc, executable=True)
self.ScratchFile('foo/foo.bzl', [
'def _impl(ctx):',
' ctx.actions.run(',
' executable=ctx.executable.tool,',
' arguments=[ctx.outputs.out.path],',
' outputs=[ctx.outputs.out])',
' return [DefaultInfo(files=depset([ctx.outputs.out]))]',
'',
'foo = rule(',
' implementation=_impl,',
' attrs={"tool": attr.label(executable=True, cfg="host",',
' allow_files=True, single_file=True)},',
' outputs={"out": "%{name}.txt"},',
')',
])
self.ScratchFile('foo/BUILD', [
'load("//foo:foo.bzl", "foo")',
'',
'genrule(',
' name = "genrule",',
' tools = ["%s"],' % toolname,
' outs = ["genrule.txt"],',
' cmd = "$(location %s) $@",' % toolname,
')',
'',
'foo(',
' name = "skylark",',
' tool = "%s",' % toolname,
')',
])
def _SpawnStrategies(self):
"""Returns the list of supported --spawn_strategy values."""
# TODO(b/37617303): make test UI-independent
exit_code, _, stderr = self.RunBazel([
'build', '--color=no', '--curses=no', '--spawn_strategy=foo',
'--noexperimental_ui'
])
self.AssertExitCode(exit_code, 2, stderr)
pattern = re.compile(
r'^ERROR:.*is an invalid value for.*Valid values are: (.*)\.$')
for line in stderr:
m = pattern.match(line)
if m:
return set(e.strip() for e in m.groups()[0].split(','))
return []
def _BuildRules(self, strategy):
def _ReadFile(path):
with open(path, 'rt') as f:
return [l.strip() for l in f]
exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-genfiles'])
self.AssertExitCode(exit_code, 0, stderr)
bazel_genfiles = stdout[0]
exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-bin'])
self.AssertExitCode(exit_code, 0, stderr)
bazel_bin = stdout[0]
# TODO(b/37617303): make test UI-independent
exit_code, _, stderr = self.RunBazel([
'build', '--verbose_failures', '--noexperimental_ui',
'--spawn_strategy=%s' % strategy, '//foo:genrule', '//foo:skylark'
])
self.AssertExitCode(exit_code, 0, stderr)
self.assertTrue(
os.path.exists(os.path.join(bazel_genfiles, 'foo/genrule.txt')))
self.assertTrue(os.path.exists(os.path.join(bazel_bin, 'foo/skylark.txt')))
return {
'genrule': _ReadFile(os.path.join(bazel_genfiles, 'foo/genrule.txt')),
'skylark': _ReadFile(os.path.join(bazel_bin, 'foo/skylark.txt'))
}
def _AssertOutputFileContents(self, lines):
if test_base.TestBase.IsWindows():
self.assertGreater(len(lines), 5)
self.assertEqual(lines[0], 'foo1')
self.assertEqual(lines[1], 'foo2')
self.assertEqual(lines[2], 'bar')
self.assertEqual(len([l for l in lines if l.startswith('TMP')]), 1)
self.assertEqual(len([l for l in lines if l.startswith('TEMP')]), 1)
else:
self.assertGreater(len(lines), 3)
self.assertEqual(lines[0], 'foo')
self.assertEqual(lines[1], 'bar')
self.assertEqual(len([l for l in lines if l.startswith('TMPDIR')]), 1)
if __name__ == '__main__':
unittest.main()