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