Getting most of the tests running on Windows. This adds proper iree_cc_test and iree_lit_test execution via cmake test on Windows. A handful of tests are failing due to file IO issues that will be fixed in follow-on changes. Closes https://github.com/google/iree/pull/899 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/iree/pull/899 from google:benvanik-win32-test 1ef44695c721f0edc82e49aec3737e18356bbbe8 PiperOrigin-RevId: 298599246
diff --git a/build_tools/cmake/iree_cc_test.cmake b/build_tools/cmake/iree_cc_test.cmake index 3166c7f..eeaf651 100644 --- a/build_tools/cmake/iree_cc_test.cmake +++ b/build_tools/cmake/iree_cc_test.cmake
@@ -103,7 +103,21 @@ set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${IREE_CXX_STANDARD}) set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) - # We run all our tests through a custom test runner to allow setup and teardown. - add_test(NAME ${_NAME} COMMAND ${CMAKE_SOURCE_DIR}/build_tools/cmake/run_test.sh "${CMAKE_CURRENT_BINARY_DIR}/${_NAME}") - set_property(TEST ${_NAME} PROPERTY ENVIRONMENT "TEST_TMPDIR=${_NAME}_test_tmpdir") + # We run all our tests through a custom test runner to allow temp directory + # cleanup upon test completion. + add_test( + NAME + ${_NAME} + COMMAND + "${CMAKE_SOURCE_DIR}/build_tools/cmake/run_test.${IREE_HOST_SCRIPT_EXT}" + "$<TARGET_FILE:${_NAME}>" + WORKING_DIRECTORY + "${CMAKE_BINARY_DIR}" + ) + set_property( + TEST + ${_NAME} + PROPERTY + ENVIRONMENT "TEST_TMPDIR=${_NAME}_test_tmpdir" + ) endfunction()
diff --git a/build_tools/cmake/iree_lit_test.cmake b/build_tools/cmake/iree_lit_test.cmake index 6620769..0874119 100644 --- a/build_tools/cmake/iree_lit_test.cmake +++ b/build_tools/cmake/iree_lit_test.cmake
@@ -45,13 +45,38 @@ get_filename_component(_TEST_FILE_PATH ${_RULE_TEST_FILE} ABSOLUTE) + set(_DATA_DEP_PATHS) + foreach(_DATA_DEP ${_RULE_DATA}) + string(REPLACE "::" "_" _DATA_DEP_NAME ${_DATA_DEP}) + # TODO(*): iree_sh_binary so we can avoid this. + if("${_DATA_DEP_NAME}" STREQUAL "iree_tools_IreeFileCheck") + list(APPEND _DATA_DEP_PATHS "${CMAKE_SOURCE_DIR}/iree/tools/IreeFileCheck.bat") + else() + list(APPEND _DATA_DEP_PATHS $<TARGET_FILE:${_DATA_DEP_NAME}>) + endif() + endforeach(_DATA_DEP) + + # We run all our tests through a custom test runner to allow setup and teardown. add_test( - NAME ${_NAME} - # We run all our tests through a custom test runner to allow setup and teardown. - COMMAND ${CMAKE_SOURCE_DIR}/build_tools/cmake/run_test.sh ${CMAKE_SOURCE_DIR}/iree/tools/run_lit.sh ${_TEST_FILE_PATH} - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" # Make sure the lit runner can find all the binaries + NAME + ${_NAME} + COMMAND + "${CMAKE_SOURCE_DIR}/build_tools/cmake/run_test.${IREE_HOST_SCRIPT_EXT}" + "${CMAKE_SOURCE_DIR}/iree/tools/run_lit.${IREE_HOST_SCRIPT_EXT}" + ${_TEST_FILE_PATH} + ${_DATA_DEP_PATHS} + WORKING_DIRECTORY + "${CMAKE_BINARY_DIR}" ) - set_property(TEST ${_NAME} PROPERTY ENVIRONMENT "TEST_TMPDIR=${_NAME}_test_tmpdir") + set_property( + TEST + ${_NAME} + PROPERTY + ENVIRONMENT + "TEST_TMPDIR=${_NAME}_test_tmpdir" + REQUIRED_FILES + "${_TEST_FILE_PATH}" + ) # TODO(gcmn): Figure out how to indicate a dependency on _RULE_DATA being built endfunction()
diff --git a/build_tools/cmake/iree_macros.cmake b/build_tools/cmake/iree_macros.cmake index 4afc54e..683460a 100644 --- a/build_tools/cmake/iree_macros.cmake +++ b/build_tools/cmake/iree_macros.cmake
@@ -15,6 +15,16 @@ include(CMakeParseArguments) #------------------------------------------------------------------------------- +# Missing CMake Variables +#------------------------------------------------------------------------------- + +if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") + set(IREE_HOST_SCRIPT_EXT "bat") +else() + set(IREE_HOST_SCRIPT_EXT "sh") +endif() + +#------------------------------------------------------------------------------- # Packages and Paths #-------------------------------------------------------------------------------
diff --git a/build_tools/cmake/run_test.bat b/build_tools/cmake/run_test.bat new file mode 100644 index 0000000..61f5fe0 --- /dev/null +++ b/build_tools/cmake/run_test.bat
@@ -0,0 +1,18 @@ +@ECHO OFF +REM Copyright 2020 Google LLC +REM +REM Licensed under the Apache License, Version 2.0 (the "License"); +REM you may not use this file except in compliance with the License. +REM You may obtain a copy of the License at +REM +REM https://www.apache.org/licenses/LICENSE-2.0 +REM +REM Unless required by applicable law or agreed to in writing, software +REM distributed under the License is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM See the License for the specific language governing permissions and +REM limitations under the License. + +SET RUNNER_PATH=%~dp0 +powershell.exe -NoProfile -File "%RUNNER_PATH%\run_test.ps1" %* +EXIT /B %ERRORLEVEL%
diff --git a/build_tools/cmake/run_test.ps1 b/build_tools/cmake/run_test.ps1 new file mode 100644 index 0000000..eab362d --- /dev/null +++ b/build_tools/cmake/run_test.ps1
@@ -0,0 +1,76 @@ +# Copyright 2020 Google LLC +# +# 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 +# +# https://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. + +param( + [Parameter(Position=0, Mandatory)] + [ValidateNotNullOrEmpty()] + [string] + $test_binary, + [Parameter(Position=1, ValueFromRemainingArguments=$true)] + [string[]] + $test_args = @() +) + +# NOTE: to debug first run `$DebugPreference = 'Continue'` in your shell. +# $DebugPreference = "Continue" + +# Create/cleanup the test output directory (where gtest files are written, etc). +$test_tmpdir = $env:TEST_TMPDIR +if ($null -eq $test_tmpdir) { + Write-Error "TEST_TMPDIR environment variable not set" -Category InvalidArgument + Get-ChildItem env: + exit 1 +} +Write-Debug "Preparing test output path $test_tmpdir..." +if (Test-Path $test_tmpdir) { + Write-Debug "Removing existing folder at $test_tmpdir" + Remove-Item $test_tmpdir -Recurse -Force +} +New-Item -Path $test_tmpdir -ItemType Directory -Force | Out-Null +Write-Debug "Created new folder at $test_tmpdir" +trap { + if (Test-Path $test_tmpdir) { + Write-Debug "Cleaning up $test_tmpdir on error..." + Remove-Item $test_tmpdir -Recurse -Force + } + Write-Error $_ + exit 1 +} + +# Run the test executable with all arguments we were passed. +Write-Host -ForegroundColor Blue "Running test:" +Write-Host -ForegroundColor Yellow "$test_binary $test_args" +$process = $null +if ($test_args.Count -gt 0) { + $process = Start-Process -FilePath $test_binary -ArgumentList $test_args -NoNewWindow -PassThru +} else { + $process = Start-Process -FilePath $test_binary -NoNewWindow -PassThru +} +# HACK: Start-Process is broken... wow. +# https://stackoverflow.com/questions/10262231/obtaining-exitcode-using-start-process-and-waitforexit-instead-of-wait +$handle = $process.Handle +$exitcode = 1 +$timeout_millis = 120 * 1000 +if ($process.WaitForExit($timeout_millis) -eq $false) { + Write-Error "Test timed out after $timeout_millis millis" +} else { + $exitcode = $process.ExitCode + Write-Debug "Test returned in time with exit code $($process.ExitCode)" +} + +# Cleanup test tempdir. +Write-Debug "Cleaning up $test_tmpdir..." +Remove-Item $test_tmpdir -Recurse -Force +Write-Debug "Test exited with $exitcode" +exit $exitcode
diff --git a/iree/base/internal/file_handle_win32.cc b/iree/base/internal/file_handle_win32.cc index 4517943..ae69b60 100644 --- a/iree/base/internal/file_handle_win32.cc +++ b/iree/base/internal/file_handle_win32.cc
@@ -47,6 +47,22 @@ return absl::make_unique<FileHandle>(handle, file_size); } +// static +StatusOr<std::unique_ptr<FileHandle>> FileHandle::OpenWrite(std::string path, + DWORD file_flags) { + HANDLE handle = ::CreateFileA( + /*lpFileName=*/path.c_str(), /*dwDesiredAccess=*/GENERIC_WRITE, + /*dwShareMode=*/FILE_SHARE_DELETE, /*lpSecurityAttributes=*/nullptr, + /*dwCreationDisposition=*/CREATE_ALWAYS, + /*dwFlagsAndAttributes=*/FILE_ATTRIBUTE_NORMAL | file_flags, + /*hTemplateFile=*/nullptr); + if (handle == INVALID_HANDLE_VALUE) { + return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC) + << "Unable to open file " << path; + } + return absl::make_unique<FileHandle>(handle, 0); +} + FileHandle::~FileHandle() { ::CloseHandle(handle_); } } // namespace iree
diff --git a/iree/base/internal/file_handle_win32.h b/iree/base/internal/file_handle_win32.h index 297dd20..70e5113 100644 --- a/iree/base/internal/file_handle_win32.h +++ b/iree/base/internal/file_handle_win32.h
@@ -32,6 +32,8 @@ public: static StatusOr<std::unique_ptr<FileHandle>> OpenRead(std::string path, DWORD file_flags); + static StatusOr<std::unique_ptr<FileHandle>> OpenWrite(std::string path, + DWORD file_flags); FileHandle(HANDLE handle, size_t size) : handle_(handle), size_(size) {} ~FileHandle();
diff --git a/iree/base/internal/file_io_win32.cc b/iree/base/internal/file_io_win32.cc index 8486b94..68e044b 100644 --- a/iree/base/internal/file_io_win32.cc +++ b/iree/base/internal/file_io_win32.cc
@@ -53,8 +53,14 @@ } Status SetFileContents(const std::string& path, const std::string& content) { - return UnimplementedErrorBuilder(IREE_LOC) - << "SetFileContents unimplemented on Windows"; + ASSIGN_OR_RETURN(auto file, FileHandle::OpenWrite(std::move(path), 0)); + if (::WriteFile(file->handle(), content.data(), content.size(), NULL, NULL) == + FALSE) { + return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC) + << "Unable to write file span of " << content.size() << " bytes to '" + << path << "'"; + } + return OkStatus(); } Status DeleteFile(const std::string& path) {
diff --git a/iree/tools/CMakeLists.txt b/iree/tools/CMakeLists.txt index a8b3873..a1bfc73 100644 --- a/iree/tools/CMakeLists.txt +++ b/iree/tools/CMakeLists.txt
@@ -305,6 +305,9 @@ iree::tools::iree_translate_library ) + # TODO(*): define these with a rule instead (like iree_sh_binary). + # We want them to have the same package namespacing so we can reference them + # as if they were binaries (iree::tools::IreeFileCheck, etc). if(${IREE_BUILD_TESTS}) add_custom_target(IreeFileCheck ALL COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/IreeFileCheck.sh IreeFileCheck
diff --git a/iree/tools/IreeFileCheck.bat b/iree/tools/IreeFileCheck.bat new file mode 100644 index 0000000..dbd4d5f --- /dev/null +++ b/iree/tools/IreeFileCheck.bat
@@ -0,0 +1,17 @@ +@ECHO OFF +REM Copyright 2020 Google LLC +REM +REM Licensed under the Apache License, Version 2.0 (the "License"); +REM you may not use this file except in compliance with the License. +REM You may obtain a copy of the License at +REM +REM https://www.apache.org/licenses/LICENSE-2.0 +REM +REM Unless required by applicable law or agreed to in writing, software +REM distributed under the License is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM See the License for the specific language governing permissions and +REM limitations under the License. + +FileCheck --enable-var-scope --dump-input=fail %* +EXIT /B %ERRORLEVEL%
diff --git a/iree/tools/run_lit.bat b/iree/tools/run_lit.bat new file mode 100644 index 0000000..abfb082 --- /dev/null +++ b/iree/tools/run_lit.bat
@@ -0,0 +1,18 @@ +@ECHO OFF +REM Copyright 2020 Google LLC +REM +REM Licensed under the Apache License, Version 2.0 (the "License"); +REM you may not use this file except in compliance with the License. +REM You may obtain a copy of the License at +REM +REM https://www.apache.org/licenses/LICENSE-2.0 +REM +REM Unless required by applicable law or agreed to in writing, software +REM distributed under the License is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM See the License for the specific language governing permissions and +REM limitations under the License. + +SET RUNNER_PATH=%~dp0 +powershell.exe -NoProfile -File "%RUNNER_PATH%\run_lit.ps1" %* +EXIT /B %ERRORLEVEL%
diff --git a/iree/tools/run_lit.ps1 b/iree/tools/run_lit.ps1 new file mode 100644 index 0000000..fa73b2a --- /dev/null +++ b/iree/tools/run_lit.ps1
@@ -0,0 +1,63 @@ +# Copyright 2020 Google LLC +# +# 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 +# +# https://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. + +param( + [Parameter(Position=0, Mandatory)] + [ValidateNotNullOrEmpty()] + [string] + $test_file, + [Parameter(Position=1, ValueFromRemainingArguments=$true)] + [string[]] + $test_data = @() +) + +# NOTE: to debug first run `$DebugPreference = 'Continue'` in your shell. +# $DebugPreference = "Continue" + +trap { + Write-Error $_ + exit 1 +} + +# Get all of the directories we'll want to put on our path for the test. +$test_dirs = [System.Collections.ArrayList]@() +foreach ($test_path in $test_data) { + $test_dir = Split-Path -Path $test_path -Parent + $test_dirs.Add($test_dir) | Out-Null +} +Write-Debug "Test data directories: $test_dirs" +$test_dirs.AddRange($env:Path.Split(";")) +$env:Path = $test_dirs -join ";" +Write-Debug "Test PATH:" +Write-Debug "$env:PATH" + +$test_lines = Get-Content -Path $test_file +foreach ($test_line in $test_lines) { + if (!$test_line.StartsWith("// RUN:")) { + continue + } + $test_line = $test_line.Substring("// RUN: ".Length) + $test_line = $test_line -replace "%s", $test_file + Write-Host -ForegroundColor Blue "Running test command:" + Write-Host -ForegroundColor Yellow "$test_line" + & "bash.exe" -c $test_line | Out-Default + if ($LASTEXITCODE -gt 0) { + Write-Host -ForegroundColor Red "Test failed with $LASTEXITCODE, command:" + Write-Host -ForegroundColor Yellow "$test_line" + exit $LASTEXITCODE + } +} + +Write-Debug "All run commands completed successfully" +exit 0