Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/generated-bindings-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ jobs:
if: matrix.v-channel == 'stable' || steps.setup_v_source.outcome == 'success'
shell: bash
run: v run setup.vsh --check
- name: Test runtime probe execution and working directory
if: matrix.v-channel == 'stable'
shell: bash
run: python ci/test_setup_runtime.py --cc "${{ matrix.compiler }}"
- name: Accept old installed headers with bundled build inputs
if: runner.os == 'Linux' && matrix.v-channel == 'stable'
shell: bash
Expand Down
52 changes: 52 additions & 0 deletions ci/test_setup_runtime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Exercise setup's runtime probe without depending on a GPU or installed SDK."""

import argparse
import os
from pathlib import Path
import shutil
import subprocess
import tempfile


def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--v', default=os.environ.get('VEXE', 'v'))
parser.add_argument('--cc', default='msvc' if os.name == 'nt' else 'gcc')
args = parser.parse_args()
root = Path(__file__).resolve().parents[1]
compiler = shutil.which(args.v) or str(Path(args.v).resolve())
suffix = '.exe' if os.name == 'nt' else ''
with tempfile.TemporaryDirectory(prefix='vulkan setup with spaces ') as temporary:
work = Path(temporary)
probe_source = work / 'probe.v'
probe_source.write_text('''import os
fn main() {
assert os.args[1..] == ['--summary']
assert os.real_path(os.getwd()) == os.real_path(os.temp_dir())
os.write_file(os.getenv('PROBE_MARKER'), os.getwd()) or { panic(err) }
if os.getenv('PROBE_FAIL') == '1' { exit(23) }
println('GPU0: fixture')
}
''', encoding='utf-8')
probe = work / ('vulkaninfo' + suffix)
subprocess.run([compiler, '-cc', args.cc, '-o', str(probe), str(probe_source)],
check=True, cwd=root)
marker = work / 'ran.txt'
env = dict(os.environ, PATH=str(work) + os.pathsep + os.environ['PATH'],
PROBE_MARKER=str(marker))
for failure in ['0', '1']:
env['PROBE_FAIL'] = failure
result = subprocess.run([compiler, '-cc', args.cc, 'run', str(root / 'setup.vsh'),
'--check'], cwd=root, env=env,
capture_output=True, text=True, check=True)
print(result.stdout)
assert marker.is_file(), 'vulkaninfo never ran'
expected = ('[ok] Vulkan loader enumerated a physical device' if failure == '0'
else '[warning] vulkaninfo is installed, but no usable device was enumerated')
assert expected in result.stdout, result.stdout + result.stderr
marker.unlink()
print('Setup runtime probe tests passed.')


if __name__ == '__main__':
main()
12 changes: 11 additions & 1 deletion setup.vsh
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,17 @@ fn check() bool {
if command_exists('vulkaninfo') {
// Some SDK builds write their update manifest into the process working
// directory. Keep diagnostics from leaving residue in the user's repo.
result := os.execute('cd ${os.quoted_path(os.temp_dir())} && vulkaninfo --summary')
original_directory := os.getwd()
os.chdir(os.temp_dir()) or {
println('[warning] Could not enter the temporary directory for Vulkan diagnostics: ${err}')
return ok
}
defer {
os.chdir(original_directory) or {}
}
// V's Windows os.execute rejects shell command chaining. Change the
// directory through the OS API so the probe actually runs on Windows.
result := os.execute('vulkaninfo --summary')
if result.exit_code == 0 {
println('[ok] Vulkan loader enumerated a physical device')
} else {
Expand Down
Loading