Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
411e6061
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
411e6061
编写于
6月 30, 2017
作者:
J
Jared Parsons
提交者:
GitHub
6月 30, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #20570 from jaredpar/fix-det-script
Cleanup the test-determinism script
上级
66fc8d0d
9be70935
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
116 addition
and
100 deletion
+116
-100
build/scripts/test-determinism.ps1
build/scripts/test-determinism.ps1
+116
-100
未找到文件。
build/scripts/test-determinism.ps1
浏览文件 @
411e6061
[
CmdletBinding
(
PositionalBinding
=
$false
)]
param
(
[
string
]
$bootstrapDir
=
""
,
[
bool
]
$debugDeterminism
=
$false
)
[
switch
]
$debugDeterminism
=
$false
)
Set-StrictMode
-version
2.0
$Error
ActionPreference
=
"Stop"
...
...
@@ -11,124 +11,137 @@ $ErrorActionPreference = "Stop"
# makes them non-deterministic.
$
script
:
skipList
=
@()
# Holds the determinism data checked on every build.
$
script
:
dataMap
=
@{}
# Location that deterministic error information should be written to.
[
string
]
$
script
:
errorDir
=
""
[
string
]
$
script
:
errorDirLeft
=
""
[
string
]
$
script
:
errorDirRight
=
""
function
Run-Build
()
{
param
(
[
string
]
$rootDir
=
$
(
throw
"Need a root directory to build"
),
[
string
]
$pathMapBuildOption
=
""
,
[
switch
]
$restore
=
$false
)
$sln
=
Join-Path
$rootDir
"Roslyn.sln"
$debugDir
=
Join-Path
$rootDir
"Binaries\Debug"
$objDir
=
Join-Path
$rootDir
"Binaries\Obj"
# Create directories that may or may not exist to make the script execution below
# clean in either case.
Create-Directory
$debugDir
Create-Directory
$objDir
function
Run-Build
([
string
]
$rootDir
,
[
string
]
$pathMapBuildOption
,
[
switch
]
$restore
=
$false
)
{
Push-Location
$rootDir
try
{
# Clean out the previous run
Write-Host
"Cleaning the Binaries"
Exec-Command
$msbuild
"/nologo /v:m /nodeReuse:false /t:clean
$sln
"
Exec-Command
$msbuild
"/nologo /v:m /nodeReuse:false /t:clean
Roslyn.sln"
if
(
$restore
)
{
Write-Host
"Restoring the packages"
Restore-Project
-fileName
$sln
-nuget
(
Ensure-NuGet
)
-msbuildDir
(
Split-Path
-parent
$msbuild
)
Restore-Project
-fileName
"Roslyn.sln"
-nuget
(
Ensure-NuGet
)
-msbuildDir
(
Split-Path
-parent
$msbuild
)
}
Write-Host
"Building the Solution"
Exec-Command
$msbuild
"/nologo /v:m /nodeReuse:false /m /p:DebugDeterminism=true /p:BootstrapBuildPath=
$
script
:
bootstrapDir
/p:Features=
`"
debug-determinism
`"
/p:UseRoslynAnalyzers=false
$pathMapBuildOption
$
sln
"
Exec-Command
$msbuild
"/nologo /v:m /nodeReuse:false /m /p:DebugDeterminism=true /p:BootstrapBuildPath=
$
script
:
bootstrapDir
/p:Features=
`"
debug-determinism
`"
/p:UseRoslynAnalyzers=false
$pathMapBuildOption
Roslyn.
sln"
}
finally
{
Pop-Location
}
}
function
Run-Analysis
()
{
param
(
[
string
]
$rootDir
=
$
(
throw
"Need a root directory to build"
),
[
bool
]
$buildMap
=
$
(
throw
"Whether to build the map or analyze it"
),
[
string
]
$pathMapBuildOption
=
""
,
[
switch
]
$restore
=
$false
)
$debugDir
=
Join-Path
$rootDir
"Binaries\Debug"
$errorList
=
@()
$allGood
=
$true
Run-Build
$rootDir
$pathMapBuildOption
-restore
:
$restore
function
Get-ObjDir
([
string
]
$rootDir
)
{
return
Join-Path
$rootDir
"Binaries\Obj"
}
Push-Location
$debugDir
# Return all of the files that need to be processed for determinism under the given
# directory.
function
Get-FilesToProcess
([
string
]
$rootDir
)
{
$objDir
=
Get-ObjDir
$rootDir
foreach
(
$item
in
Get-ChildItem
-re
-in
*.
dll
,
*.
exe
$objDir
)
{
$fileFullName
=
$item
.
FullName
$fileName
=
Split-Path
-leaf
$fileFullName
Write-Host
"Testing the binaries"
foreach
(
$dll
in
gci
-re
-in
*.
dll
,
*.
exe
)
{
$dllFullName
=
$dll
.
FullName
$dllId
=
$dllFullName
.
Substring
(
$debugDir
.
Length
)
$dllName
=
Split-Path
-leaf
$dllFullName
$dllHash
=
(
get-filehash
$dll
-algorithm
MD5
)
.
Hash
$keyFullName
=
$dllFullName
+
".key"
$keyName
=
Split-Path
-leaf
$keyFullName
# Do not process binaries that have been explicitly skipped or do not have a key
# file. The lack of a key file means it's a binary that wasn't specifically
# built for that directory (dependency). Only need to check the binaries we are
# building.
if
(
$
script
:
skipList
.
Contains
(
$dllName
)
-or
-not
(
test-path
$keyFullName
))
{
if
(
$skipList
.
Contains
(
$fileName
))
{
continue
;
}
if
(
$buildMap
)
{
Write-Host
"
`t
Recording
$dllName
=
$dllHash
"
$data
=
@{}
$data
[
"Hash"
]
=
$dllHash
$data
[
"Content"
]
=
[
IO.File
]::
ReadAllBytes
(
$dllFullName
)
$data
[
"Key"
]
=
[
IO.File
]::
ReadAllBytes
(
$dllFullName
+
".key"
)
$
script
:
dataMap
[
$dllId
]
=
$data
}
elseif
(
-not
$
script
:
dataMap
.
Contains
(
$dllId
))
{
Write-Host
"Missing entry in map
$dllId
->
$dllFullName
"
$allGood
=
$false
}
else
{
$data
=
$
script
:
dataMap
[
$dllId
]
$oldHash
=
$data
.
Hash
if
(
$oldHash
-eq
$dllHash
)
{
Write-Host
"
`t
Verified
$dllName
"
}
else
{
Write-Host
"
`t
ERROR!
$dllName
"
$allGood
=
$false
$errorList
+=
$dllName
# Save out the original and baseline so Jenkins will archive them for investigation
[
IO.File
]::
WriteAllBytes
((
Join-Path
$
script
:
errorDirLeft
$dllName
),
$data
.
Content
)
[
IO.File
]::
WriteAllBytes
((
Join-Path
$
script
:
errorDirLeft
$keyName
),
$data
.
Key
)
cp
$dllFullName
(
Join-Path
$
script
:
errorDirRight
$dllName
)
cp
$keyFullName
(
Join-Path
$
script
:
errorDirRight
$keyName
)
}
}
$fileId
=
$fileFullName
.
Substring
(
$objDir
.
Length
)
.
Replace
(
"\"
,
"."
)
$fileHash
=
(
Get-FileHash
$fileFullName
-algorithm
MD5
)
.
Hash
$data
=
@{}
$data
.
Hash
=
$fileHash
$data
.
Content
=
[
IO.File
]::
ReadAllBytes
(
$fileFullName
)
$data
.
FileId
=
$fileId
$data
.
FileName
=
$fileName
$data
.
FileFullName
=
$fileFullName
Write-Output
$data
}
}
Pop-Location
# This will build up the map of all of the binaries and their respective hashes.
function
Record-Binaries
([
string
]
$rootDir
)
{
Write-Host
"Recording file hashes"
# During determinism debugging shutdown the compiler after every pass so we get a unique
# log directory.
if
(
$debugDeterminism
)
{
Get-Process
VBCSCompiler
-ErrorAction
SilentlyContinue
|
kill
$map
=
@{
}
foreach
(
$fileData
in
Get-FilesToProcess
$rootDir
)
{
Write-Host
"
`t
$(
$fileData
.
FileName
)
=
$(
$fileData
.
Hash
)
"
$map
[
$fileData
.
FileId
]
=
$fileData
}
return
$map
}
# This is a sanity check to ensure that we're actually putting the right entries into
# the core data map. Essentially to ensure things like if we change our directory layout
# that this test fails beacuse we didn't record the binaries we intended to record.
function
Test-MapContents
(
$dataMap
)
{
# Sanity check to ensure we didn't return a false positive because we failed
# to examine any binaries.
if
(
$
script
:
dataMap
.
Count
-lt
10
)
{
Write-Host
"Found no binaries to process"
$allGood
=
$false
if
(
$dataMap
.
Count
-lt
40
)
{
throw
"Didn't find the expected count of binaries"
}
# Test for some well known binaries
$list
=
@(
"Microsoft.CodeAnalysis.dll"
,
"Microsoft.CodeAnalysis.CSharp.dll"
,
"Microsoft.CodeAnalysis.Workspaces.dll"
,
"Microsoft.VisualStudio.LanguageServices.Implementation.dll"
)
foreach
(
$fileName
in
$list
)
{
$found
=
$false
foreach
(
$value
in
$dataMap
.
Values
)
{
if
(
$value
.
FileName
-eq
$fileName
)
{
$found
=
$true
break
;
}
}
if
(
-not
$found
)
{
throw
"Did not find the expected binary
$fileName
"
}
}
}
function
Test-Build
([
string
]
$rootDir
,
$dataMap
,
[
string
]
$pathMapBuildOption
,
[
switch
]
$restore
=
$false
)
{
Run-Build
$rootDir
$pathMapBuildOption
-restore
:
$restore
$errorList
=
@()
$allGood
=
$true
Write-Host
"Testing the binaries"
foreach
(
$fileData
in
Get-FilesToProcess
$rootDir
)
{
$fileId
=
$fileData
.
FileId
$fileName
=
$fileData
.
FileName
$fileFullName
=
$fileData
.
FileFullName
if
(
-not
$dataMap
.
Contains
(
$fileId
))
{
Write-Host
"ERROR! Missing entry in map
$fileId
->
$fileFullName
"
$allGood
=
$false
continue
}
$oldfileData
=
$datamap
[
$fileId
]
if
(
$fileData
.
Hash
-ne
$oldFileData
.
Hash
)
{
Write-Host
"
`t
ERROR!
$fileName
contents don't match"
$allGood
=
$false
$errorList
+=
$fileName
# Save out the original and baseline so Jenkins will archive them for investigation
[
IO.File
]::
WriteAllBytes
((
Join-Path
$
script
:
errorDirLeft
$fileName
),
$oldFileData
.
Content
)
Copy-Item
$fileFullName
(
Join-Path
$
script
:
errorDirRight
$fileName
)
continue
}
Write-Host
"
`t
Verified
$fileName
"
}
if
(
-not
$allGood
)
{
...
...
@@ -138,7 +151,7 @@ function Run-Analysis() {
}
Write-Host
"Archiving failure information"
$zipFile
=
Join-Path
$r
oot
Dir
"Binaries\determinism.zip"
$zipFile
=
Join-Path
$r
epo
Dir
"Binaries\determinism.zip"
Add-Type
-Assembly
"System.IO.Compression.FileSystem"
;
[
System.IO.Compression.ZipFile
]::
CreateFromDirectory
(
$
script
:
errorDir
,
$zipFile
,
"Fastest"
,
$true
);
...
...
@@ -148,31 +161,32 @@ function Run-Analysis() {
}
function
Run-Test
()
{
$
origRootDir
=
Resolve-Path
(
Split-Path
-parent
(
Split-Path
-parent
$PSScriptRoot
))
$
rootDir
=
$repoDir
# Ensure the error directory is written for all analysis to use.
$
script
:
errorDir
=
Join-Path
$
origRoot
Dir
"Binaries\Determinism"
$
script
:
errorDir
=
Join-Path
$
repo
Dir
"Binaries\Determinism"
$
script
:
errorDirLeft
=
Join-Path
$
script
:
errorDir
"Left"
$
script
:
errorDirRight
=
Join-Path
$
script
:
errorDir
"Right"
Create-Directory
$
script
:
errorDir
Create-Directory
$
script
:
errorDirLeft
Create-Directory
$
script
:
errorDirRight
# Run initial build to populate all of the expected data.
Run-Analysis
-rootDir
$origRootDir
-buildMap
$true
# Run the initial build so that we can populate the maps
Run-Build
$repoDir
$dataMap
=
Record-Binaries
$repoDir
Test-MapContents
$dataMap
# Run a
nother build in same place and verify the build is identical.
Run-Analysis
-rootDir
$origRootDir
-buildMap
$false
# Run a
test against the source in the same directory location
Test-Build
-rootDir
$repoDir
-dataMap
$dataMap
# Run another build in a different source location and verify that path mapping
# allows the build to be identical. To do this we'll copy the entire source
# tree under the Binaries\q directory and run a build from there.
$origBinDir
=
Join-Path
$origRootDir
"Binaries"
$altRootDir
=
Join-Path
$origBinDir
"q"
&
robocopy
$origRootDir
$altRootDir
/E
/XD
$origBinDir
/XD
".git"
/njh
/njs
/ndl
/nc
/ns
/np
/nfl
$pathMapBuildOption
=
"/p:PathMap=
`"
$altRootDir
=
$origRootDir
`"
"
Run-Analysis
-rootDir
$altRootDir
-buildMap
$false
-pathMapBuildOption
$pathMapBuildOption
-restore
Remove-Item
-re
-fo
$altRootDir
$altRootDir
=
Join-Path
"
$repoDir
\Binaries"
"q"
Remove-Item
-re
-fo
$altRootDir
-ErrorAction
SilentlyContinue
&
robocopy
$repoDir
$altRootDir
/E
/XD
$binariesDir
/XD
".git"
/njh
/njs
/ndl
/nc
/ns
/np
/nfl
$pathMapBuildOption
=
"/p:PathMap=
`"
$altRootDir
=
$repoDir
`"
"
Test-Build
-rootDir
$altRootDir
-dataMap
$dataMap
-pathMapBuildOption
$pathMapBuildOption
-restore
}
try
{
...
...
@@ -188,12 +202,14 @@ try {
exit
0
}
catch
{
Write-Host
"Error:
$(
$_
.
Exception
.
Message
)
"
Write-Host
$_
Write-Host
$_
.
Exception
Write-Host
$_
.
ScriptStackTrace
exit
1
}
finally
{
Write-Host
"Stopping VBCSCompiler"
Get-Process
VBCSCompiler
-ErrorAction
SilentlyContinue
|
kill
Get-Process
VBCSCompiler
-ErrorAction
SilentlyContinue
|
Stop-Process
Write-Host
"Stopped VBCSCompiler"
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录