├── .gitattributes ├── .gitignore ├── AnyOS.AnyCPU.Debug-Test-Archive-List.txt ├── BuildToolsVersion.txt ├── CONTRIBUTING.md ├── Documentation └── design │ └── dumpling │ ├── events.md │ ├── images │ └── drawing1.png │ ├── index_mvp.md │ ├── rest.md │ └── state-and-storage.md ├── DotnetCLIVersion.txt ├── LICENSE ├── README.md ├── build.cmd ├── build.proj ├── build_test.cmd ├── dir.props ├── dir.targets ├── dir.traversal.targets ├── init-tools.cmd ├── mono.targets ├── netci.groovy ├── override.targets ├── publishexe.targets ├── roslyn.xplat.targets ├── src ├── .nuget │ └── packages.Windows_NT.config ├── BuildValues.props ├── NuGet.Config ├── dir.props ├── dir.targets ├── dirs.proj ├── reliability.sln ├── stress.codegen.nuspec ├── stress.codegen │ ├── ExecutionFileGenerator.cs │ ├── GenerateStressSuiteTask.cs │ ├── HelixToFProjectFileGenerator.cs │ ├── ITestDiscoverer.cs │ ├── LoadSuiteConfig.cs │ ├── LoadSuiteGenerator.cs │ ├── LoadTestConfig.cs │ ├── LoadTestInfo.cs │ ├── LoadTestProjectFileGenerator.cs │ ├── LoadTestProjectJsonFileGenerator.cs │ ├── LoadTestSourceFileGenerator.cs │ ├── MergeAllProjectJsonsTask.cs │ ├── ProgramSourceFileGenerator.cs │ ├── ProjectJsonDependencyInfo.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── SourceFileInfo.cs │ ├── StandAloneTestDiscoverer.cs │ ├── TestAssemblyLoader.cs │ ├── ToFProjectFileGenerator.cs │ ├── UnitTestInfo.cs │ ├── UnitTestSelector.cs │ ├── XUnitTestDiscoverer.cs │ ├── app.config │ ├── packages.config │ ├── resources │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ └── runstress.sh │ ├── stress.codegen.csproj │ └── utils │ │ ├── FileUtils.cs │ │ ├── Output.cs │ │ └── RetryExtensions.cs ├── stress.execution.nuspec ├── stress.execution │ ├── ActionUnitTest.cs │ ├── AsyncWorkerStrategy.cs │ ├── DedicatedThreadWorkerStrategy.cs │ ├── ExecutionEngine.cs │ ├── FairTestPattern.cs │ ├── ILoadPattern.cs │ ├── ITestPattern.cs │ ├── IUnitTestEnumerator.cs │ ├── IWorkerStrategy.cs │ ├── LoadAttribute.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── RandomTestPattern.cs │ ├── SelfDestruct.cs │ ├── StaticLoadPattern.cs │ ├── StepLoadPattern.cs │ ├── StressTestShim.cs │ ├── TestExecutionLog.cs │ ├── UnitTest.cs │ ├── UnitTestEnumerator.cs │ ├── XunitTestAssemblyEnumerator.cs │ ├── XunitTestClassEnumerator.cs │ ├── XunitUnitTest.cs │ ├── app.config │ ├── project.json │ └── stress.execution.csproj ├── stress.run │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── project.json │ ├── stress.run.csproj │ └── stress.run.xproj ├── stress.samples │ ├── App.config │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── SimpleSample.cs │ ├── packages.config │ └── stress.samples.csproj ├── stress.tests │ ├── ArrayTests.cs │ ├── JaggedArray.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── StressTestsAssemblyTestEnumerator.cs │ ├── project.json │ └── stress.tests.csproj └── stress │ ├── App.config │ ├── CmdArgProcessing.cs │ ├── Program.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── StressEssentials.ps1 │ ├── packages.config │ └── stress.csproj ├── test ├── README.md ├── buildgen.proj ├── buildgenerated.proj ├── dir.props ├── dir.targets ├── genstress.proj └── suiteconfig │ ├── 16hr.suite.json │ ├── 1hr.suite.json │ ├── 2hr.suite.json │ ├── 4hr.suite.json │ ├── 8hr.suite.json │ ├── daily.suite.json │ └── smoketest.suite.json └── toolbox └── list_build_ids ├── DumpCore.sln ├── DumpCore.vcxproj ├── example.py ├── list_build_ids.cpp ├── python_binding.cpp └── setup.py /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | # Declare files that will always have CRLF line endings on checkout. 7 | *.sh text eol=lf 8 | 9 | ############################################################################### 10 | # Set default behavior for command prompt diff. 11 | # 12 | # This is need for earlier builds of msysgit that does not have it on by 13 | # default for csharp files. 14 | # Note: This is only used by command line 15 | ############################################################################### 16 | #*.cs diff=csharp 17 | 18 | ############################################################################### 19 | # Set the merge driver for project and solution files 20 | # 21 | # Merging from the command prompt will add diff markers to the files if there 22 | # are conflicts (Merging from VS is not affected by the settings below, in VS 23 | # the diff markers are never inserted). Diff markers may cause the following 24 | # file extensions to fail to load in VS. An alternative would be to treat 25 | # these files as binary and thus will always conflict and require user 26 | # intervention with every merge. To do so, just uncomment the entries below 27 | ############################################################################### 28 | #*.sln merge=binary 29 | #*.csproj merge=binary 30 | #*.vbproj merge=binary 31 | #*.vcxproj merge=binary 32 | #*.vcproj merge=binary 33 | #*.dbproj merge=binary 34 | #*.fsproj merge=binary 35 | #*.lsproj merge=binary 36 | #*.wixproj merge=binary 37 | #*.modelproj merge=binary 38 | #*.sqlproj merge=binary 39 | #*.wwaproj merge=binary 40 | 41 | ############################################################################### 42 | # behavior for image files 43 | # 44 | # image files are treated as binary by default. 45 | ############################################################################### 46 | #*.jpg binary 47 | #*.png binary 48 | #*.gif binary 49 | 50 | ############################################################################### 51 | # diff behavior for common document formats 52 | # 53 | # Convert binary document formats to text before diffing them. This feature 54 | # is only available from the command line. Turn it on by uncommenting the 55 | # entries below. 56 | ############################################################################### 57 | #*.doc diff=astextplain 58 | #*.DOC diff=astextplain 59 | #*.docx diff=astextplain 60 | #*.DOCX diff=astextplain 61 | #*.dot diff=astextplain 62 | #*.DOT diff=astextplain 63 | #*.pdf diff=astextplain 64 | #*.PDF diff=astextplain 65 | #*.rtf diff=astextplain 66 | #*.RTF diff=astextplain 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | 3 | ### VisualStudio ### 4 | # Tool Runtime Dir 5 | [Tt]ools/ 6 | 7 | #nuget lock files 8 | project.lock.json 9 | 10 | # User-specific files 11 | *.suo 12 | *.user 13 | *.userosscache 14 | *.sln.docstates 15 | *.VC.opendb 16 | .vs 17 | 18 | # Build results 19 | [Dd]ebug/ 20 | [Dd]ebugPublic/ 21 | [Rr]elease/ 22 | [Rr]eleases/ 23 | x64/ 24 | x86/ 25 | build/ 26 | bld/ 27 | [Bb]in/ 28 | [Oo]bj/ 29 | msbuild.log 30 | 31 | # Generated Stress Mixes 32 | /test/generated 33 | 34 | # Roslyn stuff 35 | *.sln.ide 36 | *.ide/ 37 | 38 | # MSTest test Results 39 | [Tt]est[Rr]esult*/ 40 | [Bb]uild[Ll]og.* 41 | 42 | #NUNIT 43 | *.VisualState.xml 44 | TestResult.xml 45 | 46 | # Build Results of an ATL Project 47 | [Dd]ebugPS/ 48 | [Rr]eleasePS/ 49 | dlldata.c 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opensdf 84 | *.sdf 85 | *.cachefile 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding addin-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | *.pubxml 143 | *.publishproj 144 | 145 | # NuGet Packages 146 | *.nupkg 147 | **/packages/* 148 | 149 | # Windows Azure Build Output 150 | csx/ 151 | *.build.csdef 152 | 153 | # Windows Store app package directory 154 | AppPackages/ 155 | 156 | # Others 157 | sql/ 158 | *.Cache 159 | ClientBin/ 160 | [Ss]tyle[Cc]op.* 161 | ~$* 162 | *.dbmdl 163 | *.dbproj.schemaview 164 | *.pfx 165 | *.publishsettings 166 | node_modules/ 167 | *.metaproj 168 | *.metaproj.tmp 169 | 170 | # RIA/Silverlight projects 171 | Generated_Code/ 172 | 173 | # Backup & report files from converting an old project file 174 | # to a newer Visual Studio version. Backup files are not needed, 175 | # because we have git ;-) 176 | _UpgradeReport_Files/ 177 | Backup*/ 178 | UpgradeLog*.XML 179 | UpgradeLog*.htm 180 | 181 | # SQL Server files 182 | *.mdf 183 | *.ldf 184 | 185 | # Business Intelligence projects 186 | *.rdl.data 187 | *.bim.layout 188 | *.bim_*.settings 189 | 190 | # Microsoft Fakes 191 | FakesAssemblies/ 192 | 193 | ### MonoDevelop ### 194 | 195 | *.pidb 196 | *.userprefs 197 | 198 | ### Windows ### 199 | 200 | # Windows image file caches 201 | Thumbs.db 202 | ehthumbs.db 203 | 204 | # Folder config file 205 | Desktop.ini 206 | 207 | # Recycle Bin used on file shares 208 | $RECYCLE.BIN/ 209 | 210 | # Windows Installer files 211 | *.cab 212 | *.msi 213 | *.msm 214 | *.msp 215 | 216 | # Windows shortcuts 217 | *.lnk 218 | 219 | ### Linux ### 220 | 221 | *~ 222 | 223 | # KDE directory preferences 224 | .directory 225 | 226 | ### OSX ### 227 | 228 | .DS_Store 229 | .AppleDouble 230 | .LSOverride 231 | 232 | # Icon must end with two \r 233 | Icon 234 | 235 | # Thumbnails 236 | ._* 237 | 238 | # Files that might appear on external disk 239 | .Spotlight-V100 240 | .Trashes 241 | 242 | # Directories potentially created on remote AFP share 243 | .AppleDB 244 | .AppleDesktop 245 | Network Trash Folder 246 | Temporary Items 247 | .apdisk 248 | 249 | # vim temporary files 250 | [._]*.s[a-w][a-z] 251 | [._]s[a-w][a-z] 252 | *.un~ 253 | Session.vim 254 | .netrwhist 255 | *~ 256 | 257 | local_run.rsp 258 | local_run_win10.rsp 259 | out.txt 260 | usedvalues.txt 261 | .vscode/ -------------------------------------------------------------------------------- /AnyOS.AnyCPU.Debug-Test-Archive-List.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/dotnet-reliability/6addc13cfb3c4333733e787c0c06d53921398acb/AnyOS.AnyCPU.Debug-Test-Archive-List.txt -------------------------------------------------------------------------------- /BuildToolsVersion.txt: -------------------------------------------------------------------------------- 1 | 1.0.26-prerelease-00820-01 -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Information on contributing is in the [Contributing Guide](https://github.com/dotnet/corefx/wiki/Contributing). 4 | -------------------------------------------------------------------------------- /Documentation/design/dumpling/events.md: -------------------------------------------------------------------------------- 1 | ####The Events 2 | 3 | The name scheme of the event types is: 4 | {*Emitting Service*}-{*Emitting Piece of Service*}-{*Event Type*} 5 | 6 | Where we see {os} means that any analyzer os we have setup will have a corresponding event. 7 | 8 | **rank**.`event type` 9 | 10 | 0. HelixServiceProxy-WorkItems-Status 11 | 1. DumplingService-WebAPI-StartUploadChunk 12 | 2. DumplingService-WebAPI-FinishedUploadChunk 13 | 3. DumplingService-WebAPI-Greeting 14 | 4. DumplingService-WebAPI-GetStatus 15 | 5. DumplingService-WebAPI-GetDumpURI 16 | 6. DumplingService-{os}Analyzer-StartService 17 | 7. DumplingService-{os}Analyzer-StartDownload 18 | 8. DumplingService-{os}Analyzer-StartUnzip 19 | 9. DumplingService-{os}Analyzer-StartAnalyze 20 | 10. DumplingService-{os}Analyzer-SaveResults 21 | 11. DumplingService-{os}Analyzer-Complete 22 | 12. DumplingService-{os}Analyzer-Failure 23 | 13. DumplingService-DataWorker-ReceiveMessage 24 | 14. DumplingService-DataWorker-DeadLetteredMessage 25 | 15. DumplingService-DataWorker-Exception 26 | 16. DumplingService-DataWorker-CompletedMessage 27 | 17. DumplingService-DataWorker-StartService 28 | 18. DumplingService-DataWorker-StopService 29 | 19. DumplingService-DataWorker-RunService 30 | 20. DumplingService-DataWorker-SqlIndex 31 | -------------------------------------------------------------------------------- /Documentation/design/dumpling/images/drawing1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/dotnet-reliability/6addc13cfb3c4333733e787c0c06d53921398acb/Documentation/design/dumpling/images/drawing1.png -------------------------------------------------------------------------------- /Documentation/design/dumpling/index_mvp.md: -------------------------------------------------------------------------------- 1 | ##`dumpling` service 2 | 3 | ###http://aka.ms/dumpling 4 | 5 | #####What is `dumpling` service? 6 | 7 | `dumpling` is the name of the DotNet dump analytics cli, and its storage service. Given a dump file, the service extracts information and catalogues it for future review. 8 | 9 | #####The Vision 10 | A runtime developer is looking for bugs to fix, and visits the `dumpling` website. They are presented with a view of the most impactful runtime issues. If they come across a failure they'd like to investigate, they may download the offending zipped up dump file and extract it to their machines for further review. 11 | 12 | 13 | #####`The Status`The Pieces 14 | ![For Context](images/drawing1.png) 15 | [Events that emit in to EventHub](events.md) 16 | 17 | 1. Supported Users 18 | - Automated Infrastructure 19 | - Tools 20 | - Humans 21 | 2. `stable`[RESTful Front-End](rest.md) 22 | - **upload dump file** 23 | - Get Status 24 | - Retrieve Dump File 25 | 3. `stable` [State Table](state-and-storage.md) 26 | 4. `stable` [**dump + runtime artifacts storage**](state-and-storage.md) 27 | 5. `stable`**analysis** Infrastructure 28 | - (**queue**) Azure Topic 29 | - Workers 30 | - Ubuntu 14.04 VM 31 | - CentOS VM 32 | 6. `stable` [**analysis artifacts storage**](state-and-storage.md) 33 | 7. `stable` Report Viewing 34 | - `cut?` PowerBI for high-level status 35 | - `stable` [ASP.Net WebView for actionable data](http://aka.ms/dumpling) 36 | 37 | 38 | -------------------------------------------------------------------------------- /Documentation/design/dumpling/rest.md: -------------------------------------------------------------------------------- 1 | # `dumpling` Service REST API 2 | `dumpling` should be accessible from any device that the supported DotNet runtimes are supported on. In order to enable this we're creating a simple REST interface so that a zip can be submitted from any platform. 3 | 4 | [Swagger View of API](http://dotnetrp.azurewebsites.net/swagger/ui/index) 5 | 6 | A *`dumplingid`* is a unique identifier that is assigned to a zipped up dump at the time it is uploaded. It is typed as a 'string', but its contents are nothing more than a GUID. This is *the* unique identifier of a zip file. 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Documentation/design/dumpling/state-and-storage.md: -------------------------------------------------------------------------------- 1 | #State Table 2 | Azure Storage Table 3 | 4 | Right before we begin receiving the dumpfile, we generate a dumpling-id. Upon generating the dumpling-id we create a row in the state table. The values within the state table update as dump moves through the pipeline. Upon creation the default state is 'uploading', and all of the uri values and the flight-messages are 'null'. 5 | 6 | | owner | dumpling-id | timestamp | state | symbols-uri | dump-uri | results-uri | messages | 7 | |---|---|---|---|---|---|---|---| 8 | |a |b | c | d |e |f | g | h | 9 | d: **possible states** 10 | - uploading 11 | - enqueued 12 | - downzipping 13 | - downloading symbols 14 | - analyzing 15 | - saving results 16 | - building report 17 | - done 18 | - error 19 | 20 | h: *messages* 21 | - JSON array of "message_type","message" objects 22 | 23 | #Storage 24 | 25 | **`todo`**Blob storage for the dump zip. Container names will be the value of 'owner' in the state table for the corresponding `dumpling-id`. 26 | 27 | **`stable`** Blob storage for the results json object. The container names will be the 'owner' in the state table for the corresponding `dumpling-id`. Then the first level of directory will be the `dumpling-id`. The `filename.zip` is preserved from upload. 28 | 29 | `todo`*Symbols VSTS* will store our symbol files - before this can be brought up, we must begin indexing our symbols in VSTS. There is a preview program available that I want to leverage here. 30 | 31 | -------------------------------------------------------------------------------- /DotnetCLIVersion.txt: -------------------------------------------------------------------------------- 1 | 1.0.0-preview2-002733 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## the `dumpling` service 2 | ###http://aka.ms/dumpling 3 | 4 | # dotnet-reliability 5 | Contains the tooling and infrastructure used for .NET stress testing and reliability investigation. More specifically this includes tools for, but not limited to : 6 | 7 | - authoring component specific stress and load tests 8 | - generating stress tests from existing framework and runtime tests 9 | - unified dump collection, storage, and bucketing across all .NET supported platforms 10 | - investigating and diagnosis of reliability failures 11 | 12 | -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | :: Note: We've disabled node reuse because it causes file locking issues. 5 | :: The issue is that we extend the build with our own targets which 6 | :: means that that rebuilding cannot successfully delete the task 7 | :: assembly. 8 | 9 | if not defined VisualStudioVersion ( 10 | if defined VS140COMNTOOLS ( 11 | call "%VS140COMNTOOLS%\VsDevCmd.bat" 12 | goto :EnvSet 13 | ) 14 | 15 | if defined VS120COMNTOOLS ( 16 | call "%VS120COMNTOOLS%\VsDevCmd.bat" 17 | goto :EnvSet 18 | ) 19 | 20 | echo Error: build.cmd requires Visual Studio 2013 or 2015. 21 | echo Please see https://github.com/dotnet/corefx/blob/master/Documentation/developer-guide.md for build instructions. 22 | exit /b 1 23 | ) 24 | 25 | :EnvSet 26 | 27 | call %~dp0init-tools.cmd 28 | 29 | :: Log build command line 30 | set _buildproj=%~dp0build.proj 31 | set _buildlog=%~dp0msbuild.log 32 | set _buildprefix=echo 33 | set _buildpostfix=^> "%_buildlog%" 34 | call :build %* 35 | 36 | :: Build 37 | set _buildprefix= 38 | set _buildpostfix= 39 | call :build %* 40 | 41 | goto :AfterBuild 42 | 43 | :build 44 | %_buildprefix% msbuild "%_buildproj%" /nologo /maxcpucount /verbosity:minimal /nodeReuse:false /fileloggerparameters:Verbosity=normal;LogFile="%_buildlog%";Append %* %_buildpostfix% 45 | set BUILDERRORLEVEL=%ERRORLEVEL% 46 | goto :eof 47 | 48 | :AfterBuild 49 | 50 | echo. 51 | :: Pull the build summary from the log file 52 | findstr /ir /c:".*Warning(s)" /c:".*Error(s)" /c:"Time Elapsed.*" "%_buildlog%" 53 | echo Build Exit Code = %BUILDERRORLEVEL% 54 | 55 | exit /b %BUILDERRORLEVEL% 56 | -------------------------------------------------------------------------------- /build.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | true 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | BatchRestorePackages; 23 | CreateOrUpdateCurrentVersionFile; 24 | $(TraversalBuildDependsOn); 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | <_allPackagesConfigs Include="$(MSBuildProjectDirectory)\src\**\packages.config"/> 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /build_test.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | :: Note: We've disabled node reuse because it causes file locking issues. 5 | :: The issue is that we extend the build with our own targets which 6 | :: means that that rebuilding cannot successfully delete the task 7 | :: assembly. 8 | 9 | if not defined VisualStudioVersion ( 10 | if defined VS140COMNTOOLS ( 11 | call "%VS140COMNTOOLS%\VsDevCmd.bat" 12 | goto :EnvSet 13 | ) 14 | 15 | if defined VS120COMNTOOLS ( 16 | call "%VS120COMNTOOLS%\VsDevCmd.bat" 17 | goto :EnvSet 18 | ) 19 | 20 | echo Error: build.cmd requires Visual Studio 2013 or 2015. 21 | echo Please see https://github.com/dotnet/corefx/blob/master/Documentation/developer-guide.md for build instructions. 22 | exit /b 1 23 | ) 24 | 25 | :EnvSet 26 | 27 | :: The property FilterToTestTFM is temporarily required because of https://github.com/dotnet/buildtools/commit/e9007c16b1832dbd0ea9669fa578b61900b7f724 28 | call msbuild test/genstress.proj /maxcpucount %* 29 | set BUILDERRORLEVEL=%ERRORLEVEL% 30 | 31 | 32 | exit /b %BUILDERRORLEVEL% 33 | -------------------------------------------------------------------------------- /dir.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /dir.traversal.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $(MSBuildProjectDefaultTargets) 7 | 8 | 9 | 11 | 16 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Clean 31 | 32 | 33 | 35 | 40 | 41 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | RestorePackages 57 | 58 | 59 | 61 | 66 | 67 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | BuildAllProjects; 81 | $(TraversalBuildDependsOn); 82 | 83 | 84 | 85 | CleanAllProjects; 86 | $(TraversalCleanDependsOn); 87 | 88 | 89 | 90 | RestoreAllProjectPackages; 91 | $(TraversalRestorePackagesDependsOn) 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /init-tools.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | set INIT_TOOLS_LOG=%~dp0init-tools.log 5 | set PACKAGES_DIR=%~dp0packages\ 6 | set TOOLRUNTIME_DIR=%~dp0Tools 7 | set DOTNET_PATH=%TOOLRUNTIME_DIR%\dotnetcli\ 8 | set DOTNET_CMD=%DOTNET_PATH%dotnet.exe 9 | if [%BUILDTOOLS_SOURCE%]==[] set BUILDTOOLS_SOURCE=https://dotnet.myget.org/F/dotnet-buildtools/api/v3/index.json 10 | set /P BUILDTOOLS_VERSION=< %~dp0BuildToolsVersion.txt 11 | set BUILD_TOOLS_PATH=%PACKAGES_DIR%Microsoft.DotNet.BuildTools\%BUILDTOOLS_VERSION%\lib\ 12 | set PROJECT_JSON_PATH=%TOOLRUNTIME_DIR%\%BUILDTOOLS_VERSION% 13 | set PROJECT_JSON_FILE=%PROJECT_JSON_PATH%\project.json 14 | set PROJECT_JSON_CONTENTS={ "dependencies": { "Microsoft.DotNet.BuildTools": "%BUILDTOOLS_VERSION%" }, "frameworks": { "dnxcore50": { } } } 15 | set BUILD_TOOLS_SEMAPHORE=%PROJECT_JSON_PATH%\init-tools.completed 16 | 17 | :: if force option is specified then clean the tool runtime and build tools package directory to force it to get recreated 18 | if [%1]==[force] ( 19 | if exist "%TOOLRUNTIME_DIR%" rmdir /S /Q "%TOOLRUNTIME_DIR%" 20 | if exist "%PACKAGES_DIR%Microsoft.DotNet.BuildTools" rmdir /S /Q "%PACKAGES_DIR%Microsoft.DotNet.BuildTools" 21 | ) 22 | 23 | :: If sempahore exists do nothing 24 | if exist "%BUILD_TOOLS_SEMAPHORE%" ( 25 | echo Tools are already initialized. 26 | goto :EOF 27 | ) 28 | 29 | if exist "%TOOLRUNTIME_DIR%" rmdir /S /Q "%TOOLRUNTIME_DIR%" 30 | 31 | :: Download nuget 32 | if NOT exist "%PACKAGES_DIR%\NuGet.exe" ( 33 | if NOT exist "PACKAGES_DIR" mkdir "%PACKAGES_DIR%" 34 | powershell -NoProfile -ExecutionPolicy unrestricted -Command "(New-Object Net.WebClient).DownloadFile('https://www.nuget.org/nuget.exe', '%PACKAGES_DIR%\NuGet.exe') 35 | ) 36 | 37 | if NOT exist "%PROJECT_JSON_PATH%" mkdir "%PROJECT_JSON_PATH%" 38 | echo %PROJECT_JSON_CONTENTS% > %PROJECT_JSON_FILE% 39 | echo Running %0 > %INIT_TOOLS_LOG% 40 | 41 | if exist "%DOTNET_CMD%" goto :afterdotnetrestore 42 | 43 | echo Installing dotnet cli... 44 | if NOT exist "%DOTNET_PATH%" mkdir "%DOTNET_PATH%" 45 | set /p DOTNET_VERSION=< "%~dp0DotnetCLIVersion.txt" 46 | set DOTNET_ZIP_NAME=dotnet-dev-win-x64.%DOTNET_VERSION%.zip 47 | set DOTNET_REMOTE_PATH=https://dotnetcli.blob.core.windows.net/dotnet/preview/Binaries/%DOTNET_VERSION%/%DOTNET_ZIP_NAME% 48 | set DOTNET_LOCAL_PATH=%DOTNET_PATH%%DOTNET_ZIP_NAME% 49 | echo Installing '%DOTNET_REMOTE_PATH%' to '%DOTNET_LOCAL_PATH%' >> "%INIT_TOOLS_LOG%" 50 | powershell -NoProfile -ExecutionPolicy unrestricted -Command "(New-Object Net.WebClient).DownloadFile('%DOTNET_REMOTE_PATH%', '%DOTNET_LOCAL_PATH%'); Add-Type -Assembly 'System.IO.Compression.FileSystem' -ErrorVariable AddTypeErrors; if ($AddTypeErrors.Count -eq 0) { [System.IO.Compression.ZipFile]::ExtractToDirectory('%DOTNET_LOCAL_PATH%', '%DOTNET_PATH%') } else { (New-Object -com shell.application).namespace('%DOTNET_PATH%').CopyHere((new-object -com shell.application).namespace('%DOTNET_LOCAL_PATH%').Items(),16) }" >> "%INIT_TOOLS_LOG%" 51 | if NOT exist "%DOTNET_LOCAL_PATH%" ( 52 | echo ERROR: Could not install dotnet cli correctly. See '%INIT_TOOLS_LOG%' for more details. 53 | exit /b 1 54 | ) 55 | :afterdotnetrestore 56 | 57 | if exist "%BUILD_TOOLS_PATH%" goto :afterbuildtoolsrestore 58 | echo Restoring BuildTools version %BUILDTOOLS_VERSION%... 59 | echo Running: "%DOTNET_CMD%" restore "%PROJECT_JSON_FILE%" --packages %PACKAGES_DIR% --source "%BUILDTOOLS_SOURCE%" >> %INIT_TOOLS_LOG% 60 | call "%DOTNET_CMD%" restore "%PROJECT_JSON_FILE%" --packages %PACKAGES_DIR% --source "%BUILDTOOLS_SOURCE%" >> %INIT_TOOLS_LOG% 61 | if NOT exist "%BUILD_TOOLS_PATH%init-tools.cmd" ( 62 | echo ERROR: Could not restore build tools correctly. See '%INIT_TOOLS_LOG%' for more details. 63 | goto :EOF 64 | ) 65 | 66 | :afterbuildtoolsrestore 67 | 68 | echo Initializing BuildTools ... 69 | echo Running: "%BUILD_TOOLS_PATH%init-tools.cmd" "%~dp0" "%DOTNET_CMD%" "%TOOLRUNTIME_DIR%" >> %INIT_TOOLS_LOG% 70 | call "%BUILD_TOOLS_PATH%init-tools.cmd" "%~dp0" "%DOTNET_CMD%" "%TOOLRUNTIME_DIR%" >> %INIT_TOOLS_LOG% 71 | 72 | :: Create sempahore file 73 | echo Done initializing tools. 74 | echo Init-Tools.cmd completed for BuildTools Version: %BUILDTOOLS_VERSION% > "%BUILD_TOOLS_SEMAPHORE%" -------------------------------------------------------------------------------- /mono.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | true 12 | true 13 | 14 | 15 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /netci.groovy: -------------------------------------------------------------------------------- 1 | // Import the utility functionality. 2 | 3 | import jobs.generation.Utilities; 4 | 5 | def project = GithubProject 6 | def branch = GithubBranchName 7 | 8 | // Define build string 9 | def buildString = '''call "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\Tools\\VsDevCmd.bat" && build.cmd /p:SkipTests=true''' 10 | 11 | // Generate the builds for debug and release 12 | 13 | [true, false].each { isPR -> 14 | def newJob = job(Utilities.getFullJobName(project, '', isPR)) { 15 | steps { 16 | batchFile(buildString) 17 | } 18 | } 19 | 20 | Utilities.setMachineAffinity(newJob, 'Windows_NT', 'latest-or-auto') 21 | Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}") 22 | if (isPR) { 23 | Utilities.addGithubPRTriggerForBranch(newJob, branch, 'Innerloop Windows Debug') 24 | } 25 | else { 26 | Utilities.addGithubPushTrigger(newJob) 27 | } 28 | } -------------------------------------------------------------------------------- /override.targets: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /publishexe.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | x64 9 | win7 10 | 11 | 12 | 14 | 15 | 16 | 17 | %(FileName)%(Extension) 18 | 19 | 20 | 21 | %(FileName)%(Extension) 22 | 23 | 24 | 25 | %(Filename)%(Extension) 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | $(Outdir)$(AssemblyName).dll 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /roslyn.xplat.targets: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | false 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/.nuget/packages.Windows_NT.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/BuildValues.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 11 | 00001 12 | 13 | -------------------------------------------------------------------------------- /src/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/dir.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | $(BinDir)packages 6 | 1.0.0-alpha-00037 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/dir.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | 5 | 6 | 7 | 8 | 10 | 12 | 13 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | UpdateImportedProjectRelativePaths;$(CoreBuildDependsOn) 23 | UpdateImportedProjectRelativePaths;$(CoreCleanDependsOn) 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/dirs.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | $(ToolsDir) 24 | 25 | 26 | 27 | 28 | 29 | false 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/stress.codegen.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Microsoft.DotNet.stress.codegen 5 | 1.0.0.1 6 | DotNet Stress Code Generation 7 | sschaab@microsoft.com 8 | Microsoft 9 | 10 | Contains tooling for the source generation of .NET stress test 11 | 12 | Supported platforms: 13 | - Desktop .NET 4.6 14 | 15 | 16 | en-US 17 | https://github.com/dotnet/corefx-tools 18 | https://raw.githubusercontent.com/dotnet/corefx-tools/master/LICENSE 19 | http://go.microsoft.com/fwlink/?LinkID=288859 20 | false 21 | 22 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/stress.codegen/GenerateStressSuiteTask.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using Microsoft.Build.Framework; 10 | using Microsoft.Build.Utilities; 11 | using stress.codegen.utils; 12 | using System.Diagnostics; 13 | using System.Windows; 14 | 15 | namespace stress.codegen 16 | { 17 | public class GenerateStressSuiteTask : Task 18 | { 19 | public bool DebugWaitForInput { get; set; } 20 | 21 | public bool UseLegacyProject { get; set; } 22 | 23 | public string Seed { get; set; } 24 | 25 | [Required] 26 | public string SuiteName { get; set; } 27 | 28 | [Required] 29 | public string SuitePath { get; set; } 30 | 31 | /// 32 | /// Semicolon separated list of paths containing unit test assemblies 33 | /// 34 | [Required] 35 | public string TestPaths { get; set; } 36 | 37 | /// 38 | /// Semicolon separated list of test assembly search strings used to find test assemblies 39 | /// 40 | public string TestSearchStrings { get; set; } 41 | 42 | /// 43 | /// Semicolon separated list of paths containing framework assemblies 44 | /// 45 | [Required] 46 | public string FrameworkPaths { get; set; } 47 | 48 | /// 49 | /// Path to the json config file containing the load suite configuration details 50 | /// 51 | [Required] 52 | public string ConfigPath { get; set; } 53 | 54 | /// 55 | /// Path to the project.json package config file to be used by all tests 56 | /// 57 | public string PackageConfigPath { get; set; } 58 | 59 | /// 60 | /// Path to the cache of previously discovered tests 61 | /// 62 | public string DiscoveryCachePath { get; set; } 63 | 64 | public override bool Execute() 65 | { 66 | if (DebugWaitForInput) 67 | { 68 | MessageBox.Show($"PID:{Process.GetCurrentProcess().Id} Attach debugger now.", "Debug GenerateStressSuiteTask", MessageBoxButton.OK); 69 | } 70 | 71 | try 72 | { 73 | CodeGenOutput.Redirect(new TaskLogOutputWriter(this.Log)); 74 | 75 | LoadSuiteGenerator suiteGen = new LoadSuiteGenerator(); 76 | 77 | suiteGen.GenerateSuite(this.ParseSeed(), this.SuiteName, this.SuitePath, this.ParseTestPaths(), this.ParseSearchStrings(), this.ParseFrameworkPaths(), this.GetSuiteConfig(), this.DiscoveryCachePath, this.UseLegacyProject, this.PackageConfigPath); 78 | 79 | return true; 80 | } 81 | catch (Exception e) 82 | { 83 | this.Log.LogErrorFromException(e); 84 | 85 | return false; 86 | } 87 | } 88 | 89 | private LoadSuiteConfig GetSuiteConfig() 90 | { 91 | return LoadSuiteConfig.Deserialize(this.ConfigPath); 92 | } 93 | 94 | private string[] ParseSearchStrings() 95 | { 96 | return (this.TestSearchStrings != null) ? this.TestSearchStrings.Split(';') : null; 97 | } 98 | 99 | private string[] ParseTestPaths() 100 | { 101 | return this.TestPaths.Split(';'); 102 | } 103 | 104 | private string[] ParseFrameworkPaths() 105 | { 106 | return this.FrameworkPaths.Split(';'); 107 | } 108 | 109 | private int ParseSeed() 110 | { 111 | int seed; 112 | 113 | if (this.Seed == null || !int.TryParse(this.Seed, out seed)) 114 | { 115 | seed = new Random().Next(); 116 | } 117 | 118 | return seed; 119 | } 120 | 121 | private class TaskLogOutputWriter : IOutputWriter 122 | { 123 | private TaskLoggingHelper _logHelper; 124 | 125 | public TaskLogOutputWriter(TaskLoggingHelper logHelper) 126 | { 127 | _logHelper = logHelper; 128 | } 129 | 130 | public void WriteError(string message) 131 | { 132 | _logHelper.LogError(message); 133 | } 134 | 135 | public void WriteInfo(string message) 136 | { 137 | _logHelper.LogMessage(message); 138 | } 139 | 140 | public void WriteWarning(string message) 141 | { 142 | _logHelper.LogWarning(message); 143 | } 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/stress.codegen/ITestDiscoverer.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Reflection; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace stress.codegen 13 | { 14 | public interface ITestDiscoverer 15 | { 16 | UnitTestInfo[] GetTests(TestAssemblyInfo assembly); 17 | } 18 | 19 | public interface ISourceFileGenerator 20 | { 21 | void GenerateSourceFile(LoadTestInfo loadTest); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/stress.codegen/LoadSuiteConfig.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using Newtonsoft.Json; 6 | using stress.execution; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.IO; 10 | using System.Linq; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | 14 | namespace stress.codegen 15 | { 16 | public class LoadSuiteConfig 17 | { 18 | public LoadSuiteConfig() 19 | { 20 | this.LoadTestConfigs = new List(); 21 | } 22 | 23 | public List LoadTestConfigs; 24 | 25 | public string Host; 26 | 27 | public void Serialize(string path) 28 | { 29 | // Serialize the RunConfiguration 30 | JsonSerializer serializer = JsonSerializer.CreateDefault(); 31 | 32 | using (FileStream fs = new FileStream(path, FileMode.Create)) 33 | { 34 | using (StreamWriter writer = new StreamWriter(fs)) 35 | { 36 | serializer.Serialize(writer, this); 37 | } 38 | } 39 | } 40 | 41 | public static LoadSuiteConfig Deserialize(string path) 42 | { 43 | LoadSuiteConfig config = null; 44 | 45 | // Deserialize the RunConfiguration 46 | JsonSerializer serializer = JsonSerializer.CreateDefault(); 47 | 48 | using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) 49 | { 50 | using (StreamReader reader = new StreamReader(fs)) 51 | { 52 | JsonTextReader jReader = new JsonTextReader(reader); 53 | 54 | // Call the Deserialize method to restore the object's state. 55 | config = serializer.Deserialize(jReader); 56 | } 57 | } 58 | 59 | return config; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/stress.codegen/LoadSuiteGenerator.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using stress.codegen.utils; 6 | using stress.execution; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.IO; 10 | using System.Linq; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | 14 | namespace stress.codegen 15 | { 16 | public class LoadSuiteGenerator 17 | { 18 | private UnitTestSelector _unitTestSelector; 19 | 20 | public void GenerateSuite(int seed, string suiteName, string outputPath, string[] testPaths, string[] searchPatterns, string[] hintPaths, LoadSuiteConfig config, string cachePath = null, bool legacyProject = false, string globalPackageConfig = null) 21 | { 22 | Random rand = new Random(seed); 23 | 24 | int suiteTestCount = 0; 25 | 26 | _unitTestSelector = new UnitTestSelector(); 27 | 28 | _unitTestSelector.Initialize(seed, testPaths, searchPatterns, hintPaths, cachePath); 29 | 30 | for (int iConfig = 0; iConfig < config.LoadTestConfigs.Count; iConfig++) 31 | { 32 | var loadTestConfig = config.LoadTestConfigs[iConfig]; 33 | 34 | for (int i = 0; i < loadTestConfig.TestCount; i++) 35 | { 36 | var loadTestInfo = new LoadTestInfo(globalPackageConfig) 37 | { 38 | TestName = suiteName + "_" + suiteTestCount.ToString("X4"), 39 | Duration = loadTestConfig.Duration, 40 | LoadPatternType = typeof(StaticLoadPattern), //Type.GetType(loadTestConfig.LoadPattern), 41 | TestPatternType = typeof(RandomTestPattern), //Type.GetType(loadTestConfig.TestPattern), 42 | WorkerStrategyType = typeof(DedicatedThreadWorkerStrategy), //Type.GetType(loadTestConfig.WorkerStrategy), 43 | WorkerCount = loadTestConfig.NumWorkers, 44 | SelfDestruct = loadTestConfig.SelfDestruct, 45 | EnvironmentVariables = loadTestConfig.EnvironmentVariables, 46 | SuiteConfig = config, 47 | Seed = rand.Next(), 48 | }; 49 | 50 | loadTestInfo.SourceDirectory = Path.Combine(outputPath, iConfig.ToString("00") + "_" + loadTestInfo.Duration.TotalHours.ToString("00.##") + "hr", loadTestInfo.TestName); 51 | loadTestInfo.UnitTests = _unitTestSelector.NextUnitTests(loadTestConfig.NumTests).ToArray(); 52 | 53 | //build a list of all the sources files to generate for the load test 54 | var generators = new List() 55 | { 56 | new LoadTestSourceFileGenerator(), 57 | new ProgramSourceFileGenerator(), 58 | new ExecutionFileGeneratorWindows(), 59 | new ExecutionFileGeneratorLinux(), 60 | }; 61 | 62 | //if we want to generate a legacy project file (i.e. ToF project file) use HelixToFProjectFileGenerator otherwise use LoadTestProjectFileGenerator 63 | var projectFileGenerator = legacyProject ? (ISourceFileGenerator)new HelixToFProjectFileGenerator() : (ISourceFileGenerator)new LoadTestProjectFileGenerator(); 64 | 65 | if (!legacyProject) 66 | { 67 | generators.Add(new LoadTestProjectJsonFileGenerator()); 68 | } 69 | 70 | //I believe the project file generator must be last, becuase it depends on discovering all the other source files 71 | //however the ordering beyond that should not matter 72 | generators.Add(projectFileGenerator); 73 | 74 | this.GenerateTestSources(loadTestInfo, generators); 75 | CodeGenOutput.Info($"Generated Load Test: {loadTestInfo.TestName}"); 76 | suiteTestCount++; 77 | } 78 | } 79 | } 80 | 81 | private void GenerateTestSources(LoadTestInfo loadTest, IEnumerable sourceFileGenerators) 82 | { 83 | Directory.CreateDirectory(loadTest.SourceDirectory); 84 | 85 | CopyUnitTestAssemblyRefs(loadTest); 86 | 87 | foreach(var sourceGen in sourceFileGenerators) 88 | { 89 | sourceGen.GenerateSourceFile(loadTest); 90 | } 91 | } 92 | 93 | private void CopyUnitTestAssemblyRefs(LoadTestInfo loadTest) 94 | { 95 | string refDir = Path.Combine(loadTest.SourceDirectory, "refs"); 96 | 97 | Directory.CreateDirectory(refDir); 98 | 99 | foreach (var assmPath in loadTest.UnitTests.Select(t => t.AssemblyPath).Union(loadTest.UnitTests.SelectMany(t => t.ReferenceInfo.ReferencedAssemblies.Select(ra => ra.Path)))) 100 | { 101 | string destPath = Path.Combine(refDir, Path.GetFileName(assmPath)); 102 | 103 | if (!File.Exists(destPath)) 104 | { 105 | File.Copy(assmPath, destPath); 106 | } 107 | } 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/stress.codegen/LoadTestConfig.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace stress.codegen 12 | { 13 | public class LoadTestConfig 14 | { 15 | // The number of load tests we're generating for this template 16 | public int TestCount; 17 | 18 | // The number of unit tests in the load test 19 | public int NumTests; 20 | 21 | // The duration for this load test 22 | public TimeSpan Duration; 23 | 24 | // The number of workers used in the load test 25 | public int NumWorkers; 26 | 27 | // The unit test execution pattern for this load test 28 | public string TestPattern; 29 | 30 | //the load patern for this load test 31 | public string LoadPattern; 32 | 33 | // The execution strategy for this load test 34 | public string WorkerStrategy; 35 | 36 | //if true the load test will exit with unhandled exception to force dump collection 37 | public bool SelfDestruct; 38 | 39 | public Dictionary EnvironmentVariables; 40 | 41 | public LoadTestConfig() 42 | { 43 | EnvironmentVariables = new Dictionary(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/stress.codegen/LoadTestInfo.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Reflection; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | 13 | namespace stress.codegen 14 | { 15 | public class LoadTestInfo 16 | { 17 | private string _globalPackageConfigPath = null; 18 | 19 | public LoadTestInfo(string globalPackageConfigPath) 20 | { 21 | _globalPackageConfigPath = globalPackageConfigPath; 22 | 23 | this.SourceFiles = new List(); 24 | } 25 | 26 | public int Seed { get; set; } 27 | 28 | public string TestName { get; set; } 29 | 30 | public Type TestPatternType { get; set; } 31 | 32 | public Type LoadPatternType { get; set; } 33 | 34 | public Type WorkerStrategyType { get; set; } 35 | 36 | public TimeSpan Duration { get; set; } 37 | 38 | public int WorkerCount { get; set; } 39 | 40 | public bool SelfDestruct { get; set; } 41 | 42 | public string SourceDirectory { get; set; } 43 | 44 | public IEnumerable UnitTests { get; set; } 45 | 46 | public IList SourceFiles { get; private set; } 47 | 48 | public ProjectJsonDependencyInfo PackageInfo 49 | { 50 | get 51 | { 52 | if (string.IsNullOrEmpty(_globalPackageConfigPath)) 53 | { 54 | var jsonRefInfo = this.UnitTests.Select(ut => ut.ReferenceInfo.PackageInfo); 55 | 56 | return ProjectJsonDependencyInfo.MergeToLatest(jsonRefInfo); 57 | } 58 | else 59 | { 60 | return ProjectJsonDependencyInfo.FromFile(_globalPackageConfigPath); 61 | } 62 | } 63 | } 64 | 65 | public IEnumerable AssemblyAliases 66 | { 67 | get 68 | { 69 | return this.UnitTests.Select(t => t.AssemblyAlias).Distinct(); 70 | } 71 | } 72 | 73 | public Dictionary EnvironmentVariables { get; set; } 74 | 75 | public LoadSuiteConfig SuiteConfig { get; set; } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/stress.codegen/LoadTestProjectFileGenerator.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using stress.execution; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Reflection; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | 14 | namespace stress.codegen 15 | { 16 | public class LoadTestProjectFileGenerator : ISourceFileGenerator 17 | { 18 | public void GenerateSourceFile(LoadTestInfo loadTest) 19 | { 20 | string refSnippet = GenerateTestReferencesSnippet(loadTest); 21 | 22 | string itemSnippet = GenerateSourceFileItemsSnippet(loadTest); 23 | 24 | string propertySnippet = GenerateTestPropertiesSnippet(loadTest); 25 | 26 | //format the project template {0} source files, {1} test references, {2} test properties 27 | string projFileContent = string.Format(PROJECT_TEMPLATE, itemSnippet, refSnippet, propertySnippet); 28 | 29 | File.WriteAllText(Path.Combine(loadTest.SourceDirectory, loadTest.TestName + ".csproj"), projFileContent); 30 | } 31 | 32 | private static string GenerateTestPropertiesSnippet(LoadTestInfo loadTest) 33 | { 34 | //timeout = test duration + 5 minutes for dump processing ect. 35 | string timeoutInSeconds = Convert.ToInt32((loadTest.Duration + TimeSpan.FromMinutes(5)).TotalSeconds).ToString(); 36 | 37 | string propertyString = $@" 38 | {timeoutInSeconds}"; 39 | 40 | return propertyString; 41 | } 42 | 43 | private static string GenerateSourceFileItemsSnippet(LoadTestInfo loadTest) 44 | { 45 | StringBuilder snippet = new StringBuilder(); 46 | 47 | foreach (var file in loadTest.SourceFiles) 48 | { 49 | string itemSnippet = string.Empty; 50 | if (file.SourceFileAction == SourceFileAction.Compile) 51 | { 52 | itemSnippet = $@" 53 | "; 54 | } 55 | else if (file.SourceFileAction == SourceFileAction.Binplace) 56 | { 57 | itemSnippet = $@" 58 | 59 | PreserveNewest 60 | "; 61 | } 62 | 63 | snippet.Append(itemSnippet); 64 | } 65 | 66 | return snippet.ToString(); 67 | } 68 | 69 | private static string GenerateTestReferencesSnippet(LoadTestInfo loadTest) 70 | { 71 | HashSet uniqueAssemblies = new HashSet(); 72 | 73 | var packageInfo = loadTest.PackageInfo; 74 | 75 | StringBuilder snippet = new StringBuilder(); 76 | foreach (var test in loadTest.UnitTests) 77 | { 78 | if (uniqueAssemblies.Add(test.AssemblyName)) 79 | { 80 | string refSnippet = $@" 81 | 82 | $(MSBuildThisFileDirectory)\refs\{test.AssemblyName} 83 | {UnitTestInfo.GetAssemblyAlias(test.AssemblyName)} 84 | "; 85 | 86 | snippet.Append(refSnippet); 87 | } 88 | 89 | foreach (var assmref in test.ReferenceInfo.ReferencedAssemblies) 90 | { 91 | if (uniqueAssemblies.Add(assmref.Name) && packageInfo.dependencies[Path.GetFileNameWithoutExtension(assmref.Name)] == null) 92 | { 93 | string refSnippet = $@" 94 | 95 | $(MSBuildThisFileDirectory)\refs\{assmref.Name} 96 | {UnitTestInfo.GetAssemblyAlias(assmref.Name)} 97 | "; 98 | 99 | snippet.Append(refSnippet); 100 | } 101 | } 102 | } 103 | 104 | string stressexecutionsnippet = $@" 105 | 106 | {typeof(stress.execution.UnitTest).Assembly.Location} 107 | "; 108 | 109 | snippet.Append(stressexecutionsnippet); 110 | 111 | return snippet.ToString(); 112 | } 113 | 114 | private const string PROJECT_TEMPLATE = @" 115 | 116 | 117 | 118 | false 119 | true 120 | false 121 | stress.execution.dll 122 | 123 | 124 | {2} 125 | 126 | 127 | {0} 128 | 129 | 130 | {1} 131 | 132 | 133 | "; 134 | 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/stress.codegen/LoadTestProjectJsonFileGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace stress.codegen 9 | { 10 | public class LoadTestProjectJsonFileGenerator : ISourceFileGenerator 11 | { 12 | public void GenerateSourceFile(LoadTestInfo loadTest) 13 | { 14 | var loadTestRefInfo = loadTest.PackageInfo; 15 | 16 | var srcFilePath = Path.Combine(loadTest.SourceDirectory, "project.json"); 17 | 18 | loadTestRefInfo.ToFile(srcFilePath); 19 | 20 | loadTest.SourceFiles.Add(new SourceFileInfo("project.json", SourceFileAction.None)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/stress.codegen/MergeAllProjectJsonsTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Microsoft.Build.Framework; 6 | using Microsoft.Build.Utilities; 7 | using Newtonsoft.Json; 8 | using System.IO; 9 | using System.Diagnostics; 10 | using System.Windows; 11 | using Newtonsoft.Json.Linq; 12 | 13 | namespace stress.codegen 14 | { 15 | 16 | // This merge class walks all of the directory tree of InPath and produces a merged project json file. Then we 17 | // 'trim it down' to the type of run we'd like to support, and write that final project.json to disk at OutPath. 18 | public class MergeAllProjectJsonsTask : Task 19 | { 20 | // assumptions: 21 | // we assume that anyos test project.jsons (AND ONLY THESE; any other ones will mess up the merge) are 22 | // present in the directory or subdirectories of InPath 23 | [Required] 24 | public string InPath { get; set; } 25 | 26 | // the path to the project.json we are spawning. 27 | [Required] 28 | public string OutPath { get; set; } 29 | 30 | // not currently being used, but they exist to allow tests to be 'upgraded' in place. 31 | public string OldPrerelease { get; set; } 32 | public string NewPrerelease { get; set; } 33 | 34 | // set this to true when you want to debug. It causes a message box to show with the process id of the executing 35 | // msbuild instance that you can attach your debugger to. The execution of code will sit until you click ok. 36 | public bool Debug { get; set; } 37 | 38 | // this method walks the directory tree of inPath and uses the Newtonsoft JObject::Merge to merge together 39 | // our project jsons. 40 | // we require there to be at least ONE project.json present somewhere in the directory tree of inPath 41 | private JObject MergeProjectJsonsIn(string inPath) 42 | { 43 | var projectJsons = Directory.EnumerateFiles(InPath, "project.json", SearchOption.AllDirectories).Select(p => JObject.Parse(File.ReadAllText(p))); 44 | JObject merged = new JObject(projectJsons.First()); 45 | 46 | foreach (var file in projectJsons) 47 | { 48 | // 49 | merged.Merge(file); 50 | } 51 | 52 | return merged; 53 | } 54 | 55 | // this method: 56 | // strips out test-runtime object if it is present in the dependencies list. 57 | // removes all frameworks except for the one that is to be targeted for the run 58 | private void ProduceAnyOsProjectJson(string outPath, JObject merged, string targetFramework) 59 | { 60 | // remove test-runtime if it is present. 61 | (merged["dependencies"] as JObject)?.Property("test-runtime")?.Remove(); 62 | 63 | // remove all supports. 64 | merged["supports"]?.Children().ToList().ForEach(x => x.Remove()); 65 | 66 | // remove all frameworks except the specified one 67 | merged["frameworks"]?.Children().ToList().ForEach(x => x.Remove()); 68 | merged["frameworks"][targetFramework] = new JObject(); 69 | 70 | // since we are creating an anyos test launcher we should list all known runtimes here. 71 | merged["runtimes"] = new JObject(); 72 | merged["runtimes"]["win10-x64"] = new JObject(); 73 | merged["runtimes"]["win7-x64"] = new JObject(); 74 | merged["runtimes"]["win7-x86"] = new JObject(); 75 | merged["runtimes"]["ubuntu.14.04-x64"] = new JObject(); 76 | merged["runtimes"]["osx.10.10-x64"] = new JObject(); 77 | merged["runtimes"]["centos.7-x64"] = new JObject(); 78 | merged["runtimes"]["rhel.7-x64"] = new JObject(); 79 | merged["runtimes"]["debian.8-x64"] = new JObject(); 80 | 81 | // serialize, then write the project json file to OutPath 82 | File.WriteAllText(OutPath, JsonConvert.SerializeObject(merged)); 83 | } 84 | 85 | public override bool Execute() 86 | { 87 | if (Debug) 88 | { 89 | MessageBox.Show($"PID:{Process.GetCurrentProcess().Id} Attach debugger now.", "Debug GenerateStressSuiteTask", MessageBoxButton.OK); 90 | } 91 | 92 | ProduceAnyOsProjectJson(OutPath, MergeProjectJsonsIn(InPath), "netcoreapp1.0"); 93 | 94 | return true; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/stress.codegen/ProgramSourceFileGenerator.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace stress.codegen 13 | { 14 | public class ProgramSourceFileGenerator : ISourceFileGenerator 15 | { 16 | public void GenerateSourceFile(LoadTestInfo loadTest) 17 | { 18 | string sourceCode = $@" 19 | using System; 20 | using System.Threading; 21 | using System.Threading.Tasks; 22 | using stress.execution; 23 | 24 | namespace stress.generated 25 | {{ 26 | public static class Program 27 | {{ 28 | static private bool s_selfdestruct = {loadTest.SelfDestruct.ToString().ToLower()}; 29 | 30 | public static void Main(string[] args) 31 | {{ 32 | TimeSpan duration = TimeSpan.Parse(""{loadTest.Duration.ToString()}""); 33 | 34 | CancellationTokenSource tokenSource = new CancellationTokenSource(duration); 35 | 36 | LoadTestClass.LoadTestMethod(tokenSource.Token); 37 | 38 | if(s_selfdestruct) 39 | {{ 40 | SelfDestruct.WithException(); 41 | }} 42 | }} 43 | }} 44 | }} 45 | "; 46 | string srcFilePath = Path.Combine(loadTest.SourceDirectory, "Program.cs"); 47 | 48 | File.WriteAllText(srcFilePath, sourceCode); 49 | 50 | loadTest.SourceFiles.Add(new SourceFileInfo("Program.cs", SourceFileAction.Compile)); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/stress.codegen/ProjectJsonDependencyInfo.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Linq; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace stress.codegen 11 | { 12 | public class ProjectJsonDependencyInfo 13 | { 14 | public JObject dependencies; 15 | 16 | public JObject frameworks; 17 | 18 | public JObject runtimes; 19 | 20 | public JObject supports; 21 | 22 | public ProjectJsonDependencyInfo() 23 | { 24 | dependencies = new JObject(); 25 | 26 | frameworks = new JObject(); 27 | 28 | runtimes = new JObject(); 29 | 30 | supports = new JObject(); 31 | 32 | supports.Add("coreFx.Test.netcoreapp1.0", new JObject()); 33 | } 34 | 35 | public void ToFile(string path) 36 | { 37 | File.WriteAllText(path, JsonConvert.SerializeObject(this)); 38 | } 39 | 40 | public static ProjectJsonDependencyInfo FromFile(string path) 41 | { 42 | ProjectJsonDependencyInfo dependInfo = null; 43 | //if a project.json file exists next to the test binary load it 44 | if (File.Exists(path)) 45 | { 46 | var data = JObject.Parse(File.ReadAllText(path)); 47 | 48 | (data["dependencies"] as JObject)?.Property("test-runtime")?.Remove(); 49 | 50 | dependInfo = data.ToObject(); 51 | } 52 | 53 | return dependInfo; 54 | } 55 | 56 | public static JEnumerable FetchPrimaryDependenciesProperties(JObject projectJsonObj) 57 | { 58 | return projectJsonObj["dependencies"].Children(); 59 | } 60 | 61 | 62 | 63 | public static ProjectJsonDependencyInfo MergeToLatest(IEnumerable projectJsons, string oldprerelease = null, string newprerelease = null) 64 | { 65 | var merged = new ProjectJsonDependencyInfo(); 66 | 67 | merged.dependencies = new JObject(); 68 | 69 | foreach (var pjson in projectJsons) 70 | { 71 | if (pjson.dependencies != null) 72 | { 73 | foreach (var depend in pjson.dependencies) 74 | { 75 | var depVer = ComplexVersion.Parse(depend.Value.Value()); 76 | 77 | if (newprerelease != null && depVer.Prerelease != null && depVer.Prerelease == oldprerelease) 78 | { 79 | depVer.Prerelease = newprerelease; 80 | } 81 | 82 | //if the dependency is not present in the merged dependencies OR the version in the current pjson is a greater than the one in merged 83 | //if string.Compare returns > 0 then depend.Value is greater than the one in merged, this should mean a later version 84 | if (merged.dependencies[depend.Key] == null || (ComplexVersion.Parse(merged.dependencies[depend.Key].Value()) < depVer)) 85 | { 86 | merged.dependencies[depend.Key] = depVer.ToString(); 87 | } 88 | } 89 | } 90 | } 91 | 92 | return merged; 93 | } 94 | 95 | private class ComplexVersion 96 | { 97 | public Version StrongVersion; 98 | public string Prerelease; 99 | 100 | public static ComplexVersion Parse(string verStr) 101 | { 102 | ComplexVersion ver = null; 103 | 104 | if(verStr != null) 105 | { 106 | var splitVerStr = verStr.Split(new char[] { '-' }, 2); 107 | 108 | var strongVerStr = splitVerStr[0]; 109 | 110 | var prerelVerStr = splitVerStr.Length > 1 ? splitVerStr[1] : null; 111 | 112 | Version strongVer; 113 | 114 | if(Version.TryParse(strongVerStr, out strongVer)) 115 | { 116 | ver = new ComplexVersion() { StrongVersion = strongVer, Prerelease = prerelVerStr }; 117 | } 118 | } 119 | 120 | return ver; 121 | } 122 | 123 | public static bool operator >(ComplexVersion x, ComplexVersion y) 124 | { 125 | return (x.StrongVersion > y.StrongVersion) || (y.Prerelease == null || ((x.Prerelease != null) && (string.Compare(x.Prerelease, y.Prerelease, StringComparison.InvariantCultureIgnoreCase) > 0))); 126 | } 127 | 128 | public static bool operator <(ComplexVersion x, ComplexVersion y) 129 | { 130 | return (x.StrongVersion < y.StrongVersion) || (x.Prerelease == null && y.Prerelease != null) || ((y.Prerelease != null) && (string.Compare(x.Prerelease, y.Prerelease, StringComparison.InvariantCultureIgnoreCase) < 0)); 131 | } 132 | 133 | public override string ToString() 134 | { 135 | string verStr = this.StrongVersion.ToString(); 136 | 137 | if (!string.IsNullOrEmpty(this.Prerelease)) 138 | { 139 | verStr += "-" + this.Prerelease; 140 | } 141 | 142 | return verStr; 143 | } 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/stress.codegen/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | // 4 | 5 | using System.Reflection; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | 9 | // General Information about an assembly is controlled through the following 10 | // set of attributes. Change these attribute values to modify the information 11 | // associated with an assembly. 12 | [assembly: AssemblyTitle("stress.codegen")] 13 | [assembly: AssemblyDescription("")] 14 | [assembly: AssemblyConfiguration("")] 15 | [assembly: AssemblyCompany("")] 16 | [assembly: AssemblyProduct("stress.codegen")] 17 | [assembly: AssemblyCopyright("Copyright \u00A9 2015")] 18 | [assembly: AssemblyTrademark("")] 19 | [assembly: AssemblyCulture("")] 20 | 21 | // Setting ComVisible to false makes the types in this assembly not visible 22 | // to COM components. If you need to access a type in this assembly from 23 | // COM, set the ComVisible attribute to true on that type. 24 | [assembly: ComVisible(false)] 25 | 26 | // The following GUID is for the ID of the typelib if this project is exposed to COM 27 | [assembly: Guid("b60a62ba-77b2-49fa-94b8-cffd2c3f5825")] 28 | 29 | // Version information for an assembly consists of the following four values: 30 | // 31 | // Major Version 32 | // Minor Version 33 | // Build Number 34 | // Revision 35 | // 36 | // You can specify all the values or you can default the Build and Revision Numbers 37 | // by using the '*' as shown below: 38 | // [assembly: AssemblyVersion("1.0.*")] 39 | [assembly: AssemblyVersion("1.0.0.0")] 40 | [assembly: AssemblyFileVersion("1.0.0.0")] 41 | -------------------------------------------------------------------------------- /src/stress.codegen/SourceFileInfo.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace stress.codegen 12 | { 13 | // enum with action 14 | // Compile, Binplace, Resource 15 | public enum SourceFileAction 16 | { 17 | None, 18 | Binplace, 19 | Compile, 20 | Resource 21 | } 22 | 23 | public class SourceFileInfo 24 | { 25 | public string RelativePath { get; set; } 26 | 27 | public SourceFileAction SourceFileAction { get; set; } 28 | 29 | public SourceFileInfo() 30 | { 31 | RelativePath = ""; 32 | SourceFileAction = SourceFileAction.None; 33 | } 34 | 35 | public SourceFileInfo(string relativePath, SourceFileAction sourceFileAction) 36 | { 37 | RelativePath = relativePath; 38 | SourceFileAction = sourceFileAction; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/stress.codegen/StandAloneTestDiscoverer.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Reflection; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace stress.codegen 13 | { 14 | public class StandAloneTestDiscoverer : ITestDiscoverer 15 | { 16 | public UnitTestInfo[] GetTests(TestAssemblyInfo assemblyInfo) 17 | { 18 | List assmRefs = new List(); 19 | 20 | foreach (var assmName in assemblyInfo.Assembly.GetReferencedAssemblies()) 21 | { 22 | assmRefs.Add(assmName.Name); 23 | } 24 | 25 | UnitTestInfo[] tests = null; 26 | 27 | MethodInfo entryInfo = assemblyInfo.Assembly.EntryPoint; 28 | 29 | if (entryInfo != null) 30 | { 31 | UnitTestInfo test = new UnitTestInfo() 32 | { 33 | AssemblyPath = assemblyInfo.Assembly.Location, 34 | ReferenceInfo = assemblyInfo.ReferenceInfo, 35 | Class = new TestClassInfo { FullName = entryInfo.DeclaringType.FullName, IsAbstract = entryInfo.DeclaringType.IsAbstract, IsGenericType = entryInfo.DeclaringType.IsGenericType, IsPublic = entryInfo.DeclaringType.IsPublic }, 36 | Method = new TestMethodInfo { Name = entryInfo.Name, IsAbstract = entryInfo.IsAbstract, IsGenericMethodDefinition = entryInfo.IsGenericMethodDefinition, IsPublic = entryInfo.IsPublic, IsStatic = entryInfo.IsStatic }, 37 | }; 38 | 39 | tests = new UnitTestInfo[] { test }; 40 | } 41 | 42 | return tests ?? new UnitTestInfo[] { }; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/stress.codegen/ToFProjectFileGenerator.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace stress.codegen 13 | { 14 | public static class ToFProjectFileGenerator 15 | { 16 | public static void GenerateProjectFile(LoadTestInfo loadTest) 17 | { 18 | string refSnippet = GenerateReferencesSnippet(loadTest); 19 | string fxSnippet = GenerateFrameworkReferencesSnippet(loadTest); 20 | string itemSnippet = GenerateSourceFileItemsSnippet(loadTest); 21 | string projFileContent = string.Format(PROJECT_TEMPLATE, refSnippet, itemSnippet); //, fxSnippet); 22 | 23 | File.WriteAllText(Path.Combine(loadTest.SourceDirectory, loadTest.TestName + ".csproj"), projFileContent); 24 | } 25 | 26 | private static string GenerateSourceFileItemsSnippet(LoadTestInfo loadTest) 27 | { 28 | StringBuilder snippet = new StringBuilder(); 29 | 30 | foreach (var file in loadTest.SourceFiles) 31 | { 32 | string itemSnippet = string.Empty; 33 | if (file.SourceFileAction == SourceFileAction.Compile) 34 | { 35 | itemSnippet = $@" 36 | "; 37 | } 38 | else if (file.SourceFileAction == SourceFileAction.Binplace) 39 | { 40 | itemSnippet = $@" 41 | 42 | PreserveNewest 43 | "; 44 | } 45 | 46 | snippet.Append(itemSnippet); 47 | } 48 | 49 | return snippet.ToString(); 50 | } 51 | 52 | private static string GenerateReferencesSnippet(LoadTestInfo loadTest) 53 | { 54 | HashSet uniqueAssemblies = new HashSet(); 55 | 56 | StringBuilder snippet = new StringBuilder(); 57 | foreach (var test in loadTest.UnitTests) 58 | { 59 | if (uniqueAssemblies.Add(test.AssemblyPath)) 60 | { 61 | string refSnippet = $@" 62 | 63 | $(MSBuildThisFileDirectory)\refs\{test.AssemblyName} 64 | {UnitTestInfo.GetAssemblyAlias(test.AssemblyPath)} 65 | true 66 | "; 67 | 68 | snippet.Append(refSnippet); 69 | } 70 | 71 | foreach (var assmref in test.ReferenceInfo.ReferencedAssemblies) 72 | { 73 | if (uniqueAssemblies.Add(assmref.Path)) 74 | { 75 | string refSnippet = $@" 76 | 77 | $(MSBuildThisFileDirectory)\refs\{assmref.Name} 78 | {UnitTestInfo.GetAssemblyAlias(assmref.Path)} 79 | true 80 | "; 81 | 82 | snippet.Append(refSnippet); 83 | } 84 | } 85 | } 86 | 87 | return snippet.ToString(); 88 | } 89 | 90 | private static string GenerateFrameworkReferencesSnippet(LoadTestInfo loadTest) 91 | { 92 | HashSet uniqueAssemblies = new HashSet(); 93 | 94 | StringBuilder snippet = new StringBuilder(); 95 | 96 | AssemblyReferenceSet fxRefSet = new AssemblyReferenceSet(); 97 | 98 | foreach (var testfxRefs in loadTest.UnitTests.Select(t => t.ReferenceInfo.FrameworkReferences)) 99 | { 100 | fxRefSet.UnionWith(testfxRefs); 101 | } 102 | 103 | foreach (var fxref in fxRefSet) 104 | { 105 | string refSnippet; 106 | 107 | if (fxref.Version != "4.0.0.0") 108 | { 109 | refSnippet = $@" 110 | "; 111 | } 112 | else 113 | { 114 | refSnippet = $@" 115 | 116 | {fxref.Version} 117 | "; 118 | } 119 | 120 | snippet.Append(refSnippet); 121 | } 122 | 123 | snippet.Append(@" 124 | 125 | true 126 | 1.0.0-alpha-00003 127 | "); 128 | 129 | return snippet.ToString(); 130 | } 131 | private const string PROJECT_TEMPLATE = @" 132 | 133 | 134 | 135 | false 136 | 137 | 138 | sschaab 139 | BuildAndRun 140 | Weekly 141 | 142 | 143 | {1} 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | {0} 154 | 155 | 156 | 157 | {{7E6BD405-347A-4DDE-AE19-43372FA7D697}} 158 | 159 | 160 | 161 | "; 162 | 163 | private static readonly string[] s_systemRefs = new string[] { "System.Runtime", "System.Runtime.Extensions", "System.Linq", "System.Threading", "System.Threading.Tasks", "System.Collections" }; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/stress.codegen/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/stress.codegen/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/stress.codegen/resources/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace stress.codegen.resources { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("stress.codegen.resources.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Byte[]. 65 | /// 66 | internal static byte[] runstress { 67 | get { 68 | object obj = ResourceManager.GetObject("runstress", resourceCulture); 69 | return ((byte[])(obj)); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/stress.codegen/resources/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | runstress.sh;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 123 | 124 | -------------------------------------------------------------------------------- /src/stress.codegen/resources/runstress.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #download the dumpling client 4 | wget https://dumpling.azurewebsites.net/api/client/dumpling.py 5 | 6 | #install and make sure the client script is up to doate 7 | $HELIX_PYTHONPATH dumpling.py install --update 8 | 9 | #install the tooling without --update so that it will not pull down the debugger if it's already installed 10 | $HELIX_PYTHONPATH ~/.dumpling/dumpling.py install --full 11 | 12 | #Set the rlimit for coredumps 13 | echo "executing ulimit -c unlimited" 14 | ulimit -c unlimited 15 | 16 | 17 | echo "executing ulimit -a" 18 | ulimit -a 19 | 20 | echo 0x3F > /proc/self/coredump_filter 21 | 22 | #run the specified command line 23 | echo "executing $*" 24 | $* 25 | 26 | export _EXITCODE=$? 27 | echo command exited with ExitCode: $_EXITCODE 28 | 29 | if [ $_EXITCODE != 0 ] 30 | then 31 | #This is a temporary hack workaround for the fact that the process exits before the coredump file is completely written 32 | #We need to replace this with a more hardened way to guaruntee that we don't zip and upload before the coredump is available 33 | echo "command failed waiting for coredump" 34 | sleep 2m 35 | 36 | #test if the core file was created. 37 | #this condition makes the assumption that the file will be name either 'core' or 'core.*' and be in the current directory which is true all the distros tested so far 38 | #ideally this would be constrained more by setting /proc/sys/kernel/core_pattern to a specific file to look for 39 | #however we don't have root permissions from this script when executing in helix so this would have to depend on machine setup 40 | _corefile=$(ls $PWD | grep -E --max-count=1 '^core(\..*)?$') 41 | 42 | if [ -n '$_corefile' ] 43 | then 44 | echo "uploading core to dumpling service" 45 | 46 | echo "executing $HELIX_PYTHONPATH ~/.dumpling/dumpling.py upload --dumppath $_corefile --noprompt --triage full --displayname $STRESS_TESTID --incpaths $PWD --properties $DUMPLING_PROPERTIES" 47 | $HELIX_PYTHONPATH ~/.dumpling/dumpling.py upload --dumppath $_corefile --noprompt --triage full --displayname $STRESS_TESTID --incpaths "$PWD" --properties $DUMPLING_PROPERTIES 48 | else 49 | echo "no coredump file was found in $PWD" 50 | fi 51 | 52 | #the following code zips and uploads the entire execution directory to the helix results store 53 | #it is here as a backup source of dump file storage until we are satisfied that the uploading dumps to 54 | #the dumpling service is solid and complete. After that this can be removed as it is redundant 55 | echo "zipping work item data for coredump analysis" 56 | echo "executing $HELIX_PYTHONPATH $HELIX_SCRIPT_ROOT/zip_script.py -zipFile $HELIX_WORKITEM_ROOT/$STRESS_TESTID.zip $PWD" 57 | $HELIX_PYTHONPATH $HELIX_SCRIPT_ROOT/zip_script.py -zipFile $HELIX_WORKITEM_ROOT/$STRESS_TESTID.zip "$PWD" 58 | 59 | echo "uploading coredump zip to $HELIX_RESULTS_CONTAINER_URI$STRESS_TESTID.zip analysis" 60 | echo "executing $HELIX_PYTHONPATH $HELIX_SCRIPT_ROOT/upload_result.py -result $HELIX_WORKITEM_ROOT/$STRESS_TESTID.zip -result_name $STRESS_TESTID.zip -upload_client_type Blob" 61 | $HELIX_PYTHONPATH $HELIX_SCRIPT_ROOT/upload_result.py -result $HELIX_WORKITEM_ROOT/$STRESS_TESTID.zip -result_name $STRESS_TESTID.zip -upload_client_type Blob 62 | fi 63 | 64 | exit $_EXITCODE -------------------------------------------------------------------------------- /src/stress.codegen/stress.codegen.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B60A62BA-77B2-49FA-94B8-CFFD2C3F5825} 8 | Library 9 | Properties 10 | stress.codegen 11 | stress.codegen 12 | 512 13 | SAK 14 | SAK 15 | SAK 16 | SAK 17 | 18 | 19 | .NETFramework 20 | v4.5 21 | 22 | 23 | true 24 | full 25 | false 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | 30 | 31 | pdbonly 32 | true 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ..\..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll 44 | True 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | {7e1e57d9-8587-4ea1-86f7-02813819b118} 96 | stress.execution 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 106 | 107 | 108 | 115 | -------------------------------------------------------------------------------- /src/stress.codegen/utils/Output.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Threading; 11 | 12 | namespace stress.codegen.utils 13 | { 14 | public interface IOutputWriter 15 | { 16 | void WriteInfo(string message); 17 | 18 | void WriteWarning(string message); 19 | 20 | void WriteError(string message); 21 | } 22 | 23 | 24 | public class ConsoleOutputWriter : IOutputWriter 25 | { 26 | public void WriteInfo(string message) 27 | { 28 | WriteToConsole(message); 29 | } 30 | 31 | public void WriteWarning(string message) 32 | { 33 | WriteToConsole(message, ConsoleColor.Yellow); 34 | } 35 | 36 | public void WriteError(string message) 37 | { 38 | WriteToConsole(message, ConsoleColor.Red); 39 | } 40 | 41 | private static void WriteToConsole(string message, ConsoleColor? color = null) 42 | { 43 | lock (s_consoleLock) 44 | { 45 | var origFgColor = Console.ForegroundColor; 46 | 47 | if (color.HasValue) 48 | { 49 | Console.ForegroundColor = color.Value; 50 | } 51 | 52 | Console.WriteLine(message); 53 | 54 | Console.ForegroundColor = origFgColor; 55 | } 56 | } 57 | 58 | private static object s_consoleLock = new object(); 59 | } 60 | 61 | //if TaskLog is 62 | //outputs to the console with color formatting by default 63 | public class CodeGenOutput 64 | { 65 | private static IOutputWriter s_writer = new ConsoleOutputWriter(); 66 | 67 | private CodeGenOutput() { } 68 | 69 | //public static MSBuild.TaskLoggingHelper TaskLog { get; set; } 70 | 71 | public static void Redirect(IOutputWriter writer) 72 | { 73 | s_writer = writer; 74 | } 75 | 76 | public static void Info(string message) 77 | { 78 | s_writer.WriteInfo(message); 79 | } 80 | 81 | public static void Warning(string message) 82 | { 83 | s_writer.WriteWarning(message); 84 | } 85 | 86 | public static void Error(string message) 87 | { 88 | s_writer.WriteError(message); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/stress.execution.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Microsoft.DotNet.stress.execution 5 | 1.0.0.1 6 | DotNet Stress Execution 7 | sschaab@microsoft.com 8 | Microsoft 9 | 10 | Contains tooling for the composition of .NET stress tests 11 | 12 | Supported platforms: 13 | - Desktop .NET 4.6 14 | - .NET Core 15 | - Universal Windows Apps 10+ 16 | 17 | 18 | en-US 19 | https://github.com/dotnet/corefx-tools 20 | https://raw.githubusercontent.com/dotnet/corefx-tools/master/LICENSE 21 | http://go.microsoft.com/fwlink/?LinkID=288859 22 | false 23 | 24 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/stress.execution/ActionUnitTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace stress.execution 8 | { 9 | public class ActionUnitTest : UnitTest 10 | { 11 | public ActionUnitTest(Action action = null, bool trapExceptions = true) 12 | : base(trapExceptions) 13 | { 14 | this.Action = action; 15 | } 16 | 17 | public Action Action { get; set; } 18 | 19 | protected override void ExecuteTest() 20 | { 21 | this.Action(); 22 | } 23 | 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/stress.execution/AsyncWorkerStrategy.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading; 10 | using System.Threading.Tasks; 11 | 12 | namespace stress.execution 13 | { 14 | public class AsyncWorkerStrategy : IWorkerStrategy 15 | { 16 | public void SpawnWorker(ITestPattern pattern, CancellationToken cancelToken) 17 | { 18 | Task throwaway = this.ExecuteWorkerAsync(pattern, cancelToken); 19 | } 20 | 21 | public async Task ExecuteWorkerAsync(ITestPattern pattern, CancellationToken cancelToken) 22 | { 23 | while (!cancelToken.IsCancellationRequested) 24 | { 25 | UnitTest test = pattern.GetNextTest(); 26 | 27 | await this.ExecuteTestAsync(test, cancelToken); 28 | } 29 | } 30 | 31 | public async Task ExecuteTestAsync(UnitTest test, CancellationToken cancelToken) 32 | { 33 | TaskCompletionSource executionCancelled = new TaskCompletionSource(); 34 | 35 | Task testTask = Task.Run(() => test.Execute()); 36 | 37 | cancelToken.Register(() => executionCancelled.SetResult(null)); 38 | 39 | //if the execution is cancelled before the test is complete that test will continue running 40 | //however this should only occur when the execution has run to duration so we return to allow the process to exit 41 | await Task.WhenAny(testTask, executionCancelled.Task); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/stress.execution/DedicatedThreadWorkerStrategy.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading; 11 | using System.Threading.Tasks; 12 | 13 | namespace stress.execution 14 | { 15 | public class DedicatedThreadWorkerStrategy : IWorkerStrategy 16 | { 17 | public void SpawnWorker(UnitTest test, CancellationToken cancelToken) 18 | { 19 | Task t = new Task(() => RunWorker(test, cancelToken), TaskCreationOptions.LongRunning); 20 | 21 | t.Start(); 22 | } 23 | 24 | public void SpawnWorker(ITestPattern pattern, CancellationToken cancelToken) 25 | { 26 | Task t = new Task(() => RunWorker(pattern, cancelToken), TaskCreationOptions.LongRunning); 27 | 28 | t.Start(); 29 | } 30 | 31 | private void RunWorker(ITestPattern pattern, CancellationToken cancelToken) 32 | { 33 | while (!cancelToken.IsCancellationRequested) 34 | { 35 | UnitTest t = pattern.GetNextTest(); 36 | 37 | t.Execute(); 38 | } 39 | } 40 | 41 | private void RunWorker(UnitTest test, CancellationToken cancelToken) 42 | { 43 | while (!cancelToken.IsCancellationRequested) 44 | { 45 | test.Execute(); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/stress.execution/ExecutionEngine.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace stress.execution 12 | { 13 | public class ExecutionEngine 14 | { 15 | //public static 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/stress.execution/FairTestPattern.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace stress.execution 12 | { 13 | public class FairTestPattern : ITestPattern 14 | { 15 | private Random _rand; 16 | private IList _tests; 17 | 18 | 19 | public void Initialize(int seed, IList tests) 20 | { 21 | _rand = new Random(seed); 22 | _tests = tests; 23 | } 24 | 25 | public UnitTest GetNextTest() 26 | { 27 | return _tests[GetNextTestIndex(_tests)]; 28 | } 29 | 30 | private int GetNextTestIndex(IList tests) 31 | { 32 | long total = 0; 33 | 34 | long[] buckets = new long[tests.Count]; 35 | 36 | int i; 37 | 38 | for (i = 0; i < buckets.Length; i++) 39 | { 40 | total += tests[i].Log.ExecTime + 1; 41 | 42 | buckets[i] = total; 43 | } 44 | 45 | byte[] randBytes = new byte[16]; 46 | 47 | _rand.NextBytes(randBytes); 48 | 49 | long lRand = BitConverter.ToInt64(randBytes, 0) % total; 50 | 51 | for (i = 0; i < buckets.Length; i++) 52 | { 53 | if (lRand < buckets[i]) 54 | { 55 | break; 56 | } 57 | } 58 | 59 | return i; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/stress.execution/ILoadPattern.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading; 10 | using System.Threading.Tasks; 11 | 12 | namespace stress.execution 13 | { 14 | public interface ILoadPattern 15 | { 16 | Task ExecuteAsync(ITestPattern testPattern, IWorkerStrategy workerStrategy, CancellationToken cancelToken); 17 | 18 | void Execute(ITestPattern testPattern, IWorkerStrategy workerStrategy, CancellationToken cancelToken); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/stress.execution/ITestPattern.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace stress.execution 12 | { 13 | public interface ITestPattern 14 | { 15 | UnitTest GetNextTest(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/stress.execution/IUnitTestEnumerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace stress.execution 8 | { 9 | public interface IUnitTestEnumerator : IEnumerable 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/stress.execution/IWorkerStrategy.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading; 10 | using System.Threading.Tasks; 11 | 12 | namespace stress.execution 13 | { 14 | public interface IWorkerStrategy 15 | { 16 | void SpawnWorker(ITestPattern pattern, CancellationToken cancelToken); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/stress.execution/LoadAttribute.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace stress.execution 12 | { 13 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 14 | public sealed class LoadAttribute : Attribute 15 | { 16 | public LoadAttribute(string duration) 17 | { 18 | } 19 | 20 | public string Duration { get; private set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/stress.execution/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | // 4 | 5 | using System.Reflection; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | 9 | // General Information about an assembly is controlled through the following 10 | // set of attributes. Change these attribute values to modify the information 11 | // associated with an assembly. 12 | [assembly: AssemblyTitle("stress.execution")] 13 | [assembly: AssemblyDescription("")] 14 | [assembly: AssemblyConfiguration("")] 15 | [assembly: AssemblyCompany("")] 16 | [assembly: AssemblyProduct("stress.execution")] 17 | [assembly: AssemblyCopyright("Copyright \u00A9 2015")] 18 | [assembly: AssemblyTrademark("")] 19 | [assembly: AssemblyCulture("")] 20 | 21 | // Setting ComVisible to false makes the types in this assembly not visible 22 | // to COM components. If you need to access a type in this assembly from 23 | // COM, set the ComVisible attribute to true on that type. 24 | [assembly: ComVisible(false)] 25 | 26 | // The following GUID is for the ID of the typelib if this project is exposed to COM 27 | //[assembly: Guid("a24abffc-1a04-477b-8133-0bad6dc7f597")] 28 | 29 | // Version information for an assembly consists of the following four values: 30 | // 31 | // Major Version 32 | // Minor Version 33 | // Build Number 34 | // Revision 35 | // 36 | // You can specify all the values or you can default the Build and Revision Numbers 37 | // by using the '*' as shown below: 38 | // [assembly: AssemblyVersion("1.0.*")] 39 | [assembly: AssemblyVersion("1.0.0.0")] 40 | [assembly: AssemblyFileVersion("1.0.0.0")] 41 | -------------------------------------------------------------------------------- /src/stress.execution/RandomTestPattern.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace stress.execution 12 | { 13 | public class RandomTestPattern : ITestPattern 14 | { 15 | private Random _rand; 16 | private IList _tests; 17 | 18 | 19 | public void Initialize(int seed, IList tests) 20 | { 21 | _rand = new Random(seed); 22 | _tests = tests; 23 | } 24 | 25 | public UnitTest GetNextTest() 26 | { 27 | int idx = _rand.Next(_tests.Count); 28 | 29 | return _tests[idx]; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/stress.execution/SelfDestruct.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace stress.execution 8 | { 9 | public class SelfDestructException : Exception 10 | { 11 | public SelfDestructException() : base("The operation self destructed.") { } 12 | } 13 | 14 | public static class SelfDestruct 15 | { 16 | public static void WithException() 17 | { 18 | throw new SelfDestructException(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/stress.execution/StaticLoadPattern.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading; 10 | using System.Threading.Tasks; 11 | 12 | namespace stress.execution 13 | { 14 | public class StaticLoadPattern : ILoadPattern 15 | { 16 | public int WorkerCount { get; set; } 17 | 18 | public async Task ExecuteAsync(ITestPattern testPattern, IWorkerStrategy execStrategy, CancellationToken cancelToken) 19 | { 20 | SemaphoreSlim cancelSignaled = new SemaphoreSlim(0, 1); 21 | 22 | using (cancelToken.Register(() => cancelSignaled.Release())) 23 | { 24 | for (int i = 0; i < this.WorkerCount; i++) 25 | { 26 | execStrategy.SpawnWorker(testPattern, cancelToken); 27 | } 28 | 29 | await cancelSignaled.WaitAsync(); 30 | } 31 | } 32 | 33 | public void Execute(ITestPattern testPattern, IWorkerStrategy execStrategy, CancellationToken cancelToken) 34 | { 35 | ManualResetEventSlim cancelSignaled = new ManualResetEventSlim(false); 36 | 37 | using (cancelToken.Register(() => cancelSignaled.Set())) 38 | { 39 | for (int i = 0; i < this.WorkerCount; i++) 40 | { 41 | execStrategy.SpawnWorker(testPattern, cancelToken); 42 | } 43 | 44 | cancelSignaled.Wait(); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/stress.execution/StepLoadPattern.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading; 10 | using System.Threading.Tasks; 11 | 12 | namespace stress.execution 13 | { 14 | public class StepLoadPattern : ILoadPattern 15 | { 16 | public TimeSpan StepDuration { get; set; } 17 | 18 | public int StepIncrease { get; set; } 19 | 20 | public int MaxWorkers { get; set; } 21 | 22 | public int WorkerCount { get; private set; } 23 | 24 | public void Execute(ITestPattern testPattern, IWorkerStrategy execStrategy, CancellationToken cancelToken) 25 | { 26 | this.ExecuteAsync(testPattern, execStrategy, cancelToken).GetAwaiter().GetResult(); 27 | } 28 | 29 | public async Task ExecuteAsync(ITestPattern testPattern, IWorkerStrategy workerStrategy, CancellationToken cancelToken) 30 | { 31 | while ((!cancelToken.IsCancellationRequested) && (this.WorkerCount < this.MaxWorkers)) 32 | { 33 | this.Step(testPattern, workerStrategy, cancelToken); 34 | 35 | if ((!cancelToken.IsCancellationRequested) && (this.WorkerCount < this.MaxWorkers)) 36 | { 37 | await Task.Delay(this.StepDuration, cancelToken); 38 | } 39 | } 40 | } 41 | 42 | public void Step(ITestPattern testPattern, IWorkerStrategy workerStrategy, CancellationToken cancelToken) 43 | { 44 | for (int i = 0; !cancelToken.IsCancellationRequested && i < this.StepIncrease && this.WorkerCount <= this.MaxWorkers; i++) 45 | { 46 | workerStrategy.SpawnWorker(testPattern, cancelToken); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/stress.execution/StressTestShim.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Diagnostics; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using Xunit; 13 | using Xunit.Abstractions; 14 | 15 | namespace stress.execution 16 | { 17 | public class StressTestShim 18 | { 19 | private ITestOutputHelper _output; 20 | 21 | public StressTestShim(ITestOutputHelper output) 22 | { 23 | _output = output; 24 | 25 | _outbuff = new OutputBuffer(1024 * 20, output); 26 | } 27 | 28 | [Fact] 29 | public void ShellExecuteStressTest() 30 | { 31 | //determin if we are on a unix/linux system 32 | string file = Path.Combine(Directory.GetCurrentDirectory(), File.Exists("/etc/issue") ? "stress.sh" : "stress.bat"); 33 | 34 | ProcessStartInfo testProc; 35 | 36 | if (File.Exists("/etc/issue")) 37 | { 38 | _output.WriteLine("Setting script file permissions"); 39 | 40 | _output.WriteLine($"EXEC: chmod 777 {file}"); 41 | 42 | ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = "chmod", Arguments = $"+x {file}", UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true }; 43 | 44 | Process p = Process.Start(startInfo); 45 | 46 | p.WaitForExit(); 47 | 48 | _output.WriteLine($"Setting permissions returned: {p.ExitCode}"); 49 | 50 | if (p.ExitCode != 0) 51 | { 52 | throw new Exception($"Setting shell script permissions failed with non-zero exit code {p.ExitCode}"); // Assert.True(false, string.Format("Stress tests returned error code of {0}.", p.ExitCode)); 53 | } 54 | 55 | testProc = new ProcessStartInfo() { FileName = "bash", Arguments = file, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true }; 56 | } 57 | else 58 | { 59 | testProc = new ProcessStartInfo() { FileName = file, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true }; 60 | } 61 | 62 | var envVars = Environment.GetEnvironmentVariables(); 63 | 64 | //pass environment variables onto the child process 65 | foreach (string envVarName in envVars.Keys) 66 | { 67 | if (!testProc.Environment.ContainsKey(envVarName)) 68 | { 69 | _output.WriteLine($"SETTING VARIABLE: {envVarName}={envVars[envVarName]}"); 70 | 71 | testProc.Environment.Add(envVarName, (string)envVars[envVarName]); 72 | } 73 | } 74 | 75 | _output.WriteLine($"EXEC: {file}"); 76 | 77 | //Process 78 | Process p2 = Process.Start(testProc); 79 | 80 | Task logout = LogProcessOutputAsync(p2.StandardOutput); 81 | 82 | Task logerr = LogProcessOutputAsync(p2.StandardError); 83 | 84 | p2.WaitForExit(); 85 | 86 | if (p2.ExitCode != 0) 87 | { 88 | Task.WhenAll(logout, logerr).GetAwaiter().GetResult(); 89 | 90 | var output = _outbuff.FlushToString(); 91 | 92 | throw new Exception($"Stress test process exited with non-zero exit code {p2.ExitCode}\n\nOUTPUT:\n{output}"); // Assert.True(false, string.Format("Stress tests returned error code of {0}.", p.ExitCode)); 93 | } 94 | } 95 | 96 | public async Task LogProcessOutputAsync(StreamReader stream) 97 | { 98 | string s; 99 | 100 | while ((s = await stream.ReadLineAsync()) != null) 101 | { 102 | _outbuff.Write(s); 103 | } 104 | } 105 | 106 | private OutputBuffer _outbuff; 107 | 108 | private class OutputBuffer 109 | { 110 | private static object s_bufferlock = new object(); 111 | 112 | private int _curIx = -1; 113 | private int _size; 114 | private ITestOutputHelper _output; 115 | private char[] _buff; 116 | 117 | public OutputBuffer(int size, ITestOutputHelper output) 118 | { 119 | _buff = new char[size]; 120 | _size = size; 121 | _output = output; 122 | } 123 | 124 | public void Write(string str) 125 | { 126 | lock (s_bufferlock) 127 | { 128 | for (int i = 0; i < str.Length; i++) 129 | { 130 | Write(str[i]); 131 | } 132 | 133 | Write('\n'); 134 | } 135 | } 136 | 137 | public void Write(char val) 138 | { 139 | lock (s_bufferlock) 140 | { 141 | _buff[++_curIx % _size] = val; 142 | } 143 | } 144 | 145 | 146 | public void FlushToConsole() 147 | { 148 | _output.WriteLine(this.FlushToString()); 149 | } 150 | 151 | 152 | public string FlushToString() 153 | { 154 | lock (s_bufferlock) 155 | { 156 | if (_curIx >= _size) 157 | { 158 | _output.WriteLine(""); 159 | 160 | _output.WriteLine("--- OUTPUT TRUNCATED ---"); 161 | 162 | _output.WriteLine(""); 163 | } 164 | 165 | StringBuilder builder = new StringBuilder(); 166 | 167 | int endIx = (_curIx < _size) ? _curIx : _curIx + _size; 168 | 169 | for (int ix = (_curIx < _size) ? 0 : _curIx; ix < endIx; ix++) 170 | { 171 | builder.Append(_buff[ix % _size]); 172 | } 173 | 174 | //reset the buffer 175 | _curIx = -1; 176 | 177 | return builder.ToString(); 178 | } 179 | } 180 | } 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /src/stress.execution/TestExecutionLog.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Threading; 7 | 8 | namespace stress.execution 9 | { 10 | public class TestExecutionLog 11 | { 12 | private long _execTime = 0; 13 | private int _failedCount = 0; 14 | private int _passedCount = 0; 15 | private int _currentCount = 0; 16 | 17 | public long ExecTime { get { return _execTime; } } 18 | 19 | public int FailedCount { get { return _failedCount; } } 20 | public int PassedCount { get { return _passedCount; } } 21 | 22 | public long BeginTest() 23 | { 24 | Interlocked.Increment(ref _currentCount); 25 | 26 | return DateTime.Now.Ticks; 27 | } 28 | 29 | public void EndTest(long begin, bool pass) 30 | { 31 | Interlocked.Add(ref _execTime, DateTime.Now.Ticks - begin); 32 | 33 | Interlocked.Decrement(ref _currentCount); 34 | 35 | if (pass) 36 | { 37 | Interlocked.Increment(ref _passedCount); 38 | } 39 | else 40 | { 41 | Interlocked.Increment(ref _failedCount); 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /src/stress.execution/UnitTest.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Reflection; 7 | 8 | namespace stress.execution 9 | { 10 | public abstract class UnitTest : ITestPattern 11 | { 12 | public UnitTest(bool trapExceptions = true) 13 | { 14 | this.Log = new TestExecutionLog(); 15 | 16 | this.TrapExceptions = trapExceptions; 17 | } 18 | 19 | public bool TrapExceptions { get; set; } 20 | 21 | public TestExecutionLog Log { get; private set; } 22 | 23 | public void Execute() 24 | { 25 | long begin = this.Log.BeginTest(); 26 | 27 | if (this.TrapExceptions) 28 | { 29 | try 30 | { 31 | this.ExecuteTest(); 32 | 33 | this.Log.EndTest(begin, true); 34 | } 35 | catch 36 | { 37 | this.Log.EndTest(begin, false); 38 | } 39 | } 40 | else 41 | { 42 | this.ExecuteTest(); 43 | 44 | this.Log.EndTest(begin, true); 45 | } 46 | } 47 | 48 | protected abstract void ExecuteTest(); 49 | 50 | 51 | UnitTest ITestPattern.GetNextTest() 52 | { 53 | return this; 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/stress.execution/UnitTestEnumerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace stress.execution 9 | { 10 | public abstract class UnitTestEnumerator : IUnitTestEnumerator 11 | { 12 | public IEnumerator GetEnumerator() 13 | { 14 | return (IEnumerator)GetTests(); 15 | } 16 | 17 | protected abstract IEnumerable GetTests(); 18 | 19 | IEnumerator IEnumerable.GetEnumerator() 20 | { 21 | return ((UnitTestEnumerator)this).GetEnumerator(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/stress.execution/XunitTestAssemblyEnumerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace stress.execution 9 | { 10 | public class XunitTestAssemblyEnumerator : UnitTestEnumerator 11 | { 12 | private Assembly _assembly; 13 | 14 | public XunitTestAssemblyEnumerator(Assembly assembly) 15 | { 16 | _assembly = assembly; 17 | } 18 | 19 | protected override IEnumerable GetTests() 20 | { 21 | foreach(var typeInfo in _assembly.DefinedTypes) 22 | { 23 | var classProvider = new XunitTestClassEnumerator(typeInfo.AsType()); 24 | 25 | foreach(var test in classProvider) 26 | { 27 | yield return test; 28 | } 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/stress.execution/XunitTestClassEnumerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Reflection; 7 | 8 | namespace stress.execution 9 | { 10 | public class XunitTestClassEnumerator : UnitTestEnumerator 11 | { 12 | private Type _classType; 13 | 14 | public XunitTestClassEnumerator(Type classType) 15 | { 16 | if (classType == null) throw new ArgumentNullException("classType"); 17 | 18 | _classType = classType; 19 | 20 | } 21 | 22 | protected override IEnumerable GetTests() 23 | { 24 | var typeInfo = _classType.GetTypeInfo(); 25 | var dfltCtor = typeInfo.DeclaredConstructors.FirstOrDefault(c => c.GetParameters().Length == 0); 26 | 27 | //only provide tests if the class implemented 28 | if (!typeInfo.IsInterface && !typeInfo.IsAbstract) 29 | { 30 | foreach (var method in typeInfo.DeclaredMethods) 31 | { 32 | //if the method is instance based ignore if the type is not instantiable 33 | if (method.IsStatic || dfltCtor != null) 34 | { 35 | var attributes = method.CustomAttributes; 36 | 37 | var factAttr = attributes.FirstOrDefault(attr => attr.AttributeType.Name == "FactAttribute"); 38 | 39 | var theoryAttr = attributes.FirstOrDefault(attr => attr.AttributeType.Name == "TheoryAttribute"); 40 | 41 | if (factAttr != null || theoryAttr != null) 42 | { 43 | object[][] paramSets = theoryAttr != null ? GetTheoryParameterSets(attributes, typeInfo, dfltCtor).ToArray() : null; 44 | 45 | yield return new XunitUnitTest(method, dfltCtor, paramSets); 46 | } 47 | } 48 | } 49 | } 50 | } 51 | 52 | private IEnumerable GetTheoryParameterSets(IEnumerable attributes, TypeInfo typeInfo, ConstructorInfo dfltCtor) 53 | { 54 | foreach(var attr in attributes) 55 | { 56 | if(attr.AttributeType.Name == "InlineDataAttribute") 57 | { 58 | yield return attr.ConstructorArguments[0].Value as object[]; 59 | } 60 | else if(attr.AttributeType.Name == "MemberDataAttribute") 61 | { 62 | string memberName = attr.ConstructorArguments[0].Value as string; 63 | 64 | var member = typeInfo.DeclaredMembers.FirstOrDefault(m => m.Name == memberName); 65 | 66 | PropertyInfo prop; 67 | FieldInfo fld; 68 | MethodInfo meth; 69 | 70 | IEnumerable paramSets = null; 71 | 72 | if((prop = member as PropertyInfo) != null) 73 | { 74 | var inst = prop.GetMethod.IsStatic ? null : dfltCtor.Invoke(null); 75 | 76 | paramSets = (IEnumerable)prop.GetValue(inst); 77 | } 78 | if((fld = member as FieldInfo) != null) 79 | { 80 | var inst = dfltCtor.Invoke(null); 81 | 82 | paramSets = (IEnumerable)prop.GetValue(inst); 83 | } 84 | if((meth = member as MethodInfo) != null) 85 | { 86 | var inst = meth.IsStatic ? null : dfltCtor.Invoke(null); 87 | 88 | paramSets = (IEnumerable)prop.GetValue(inst); 89 | } 90 | 91 | if (paramSets != null) 92 | { 93 | foreach (var set in paramSets) 94 | { 95 | yield return set; 96 | } 97 | } 98 | } 99 | } 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/stress.execution/XunitUnitTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace stress.execution 9 | { 10 | public class XunitUnitTest : UnitTest 11 | { 12 | private MethodInfo _methodInfo; 13 | private ConstructorInfo _dfltCtor; 14 | private object[][] _paramSets; 15 | 16 | public XunitUnitTest(MethodInfo methodInfo, ConstructorInfo dfltCtor, object[][] paramSets) 17 | { 18 | if (methodInfo == null) throw new ArgumentNullException("methodInfo"); 19 | 20 | _methodInfo = methodInfo; 21 | _dfltCtor = dfltCtor; 22 | 23 | if(paramSets == null || paramSets.Length == 0) 24 | { 25 | _paramSets = new object[][] { null }; 26 | } 27 | } 28 | 29 | protected override void ExecuteTest() 30 | { 31 | object inst = null; 32 | 33 | if (!_methodInfo.IsStatic) 34 | { 35 | inst = _dfltCtor.Invoke(null); 36 | } 37 | 38 | foreach (var parameters in _paramSets) 39 | { 40 | _methodInfo.Invoke(inst, parameters); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/stress.execution/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/stress.execution/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "NETStandard.Library": "1.6.1", 4 | "System.Diagnostics.Process": "4.3.0", 5 | "xunit.core": "2.2.0" 6 | }, 7 | "frameworks": { 8 | "netstandard1.3": { 9 | "imports": "portable-net45+win8" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/stress.execution/stress.execution.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 14.0 7 | Debug 8 | AnyCPU 9 | {7E1E57D9-8587-4EA1-86F7-02813819B118} 10 | Library 11 | Properties 12 | stress.execution 13 | stress.execution 14 | en-US 15 | 512 16 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | v5.0 18 | 19 | 20 | false 21 | .NETPortable 22 | SAK 23 | SAK 24 | SAK 25 | SAK 26 | 27 | 28 | true 29 | full 30 | false 31 | DEBUG;TRACE 32 | prompt 33 | 4 34 | true 35 | 36 | 37 | 38 | 39 | pdbonly 40 | true 41 | TRACE 42 | prompt 43 | 4 44 | true 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 86 | -------------------------------------------------------------------------------- /src/stress.run/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Reflection; 6 | using stress.execution; 7 | using stress.tests; 8 | using System.Threading; 9 | 10 | namespace stress.run 11 | { 12 | public class Program 13 | { 14 | private static int s_workerCount = 8; 15 | private static TimeSpan s_duration = TimeSpan.FromMinutes(5); 16 | private static int s_seed = new Random().Next(); 17 | 18 | public static void Main(string[] args) 19 | { 20 | if(args.Length > 3) 21 | { 22 | PrintUsage(); 23 | return; 24 | } 25 | 26 | if(args.Length > 0 && !TimeSpan.TryParse(args[0], out s_duration)) 27 | { 28 | PrintUsage(); 29 | return; 30 | } 31 | 32 | if (args.Length > 1 && !int.TryParse(args[1], out s_workerCount)) 33 | { 34 | PrintUsage(); 35 | return; 36 | } 37 | 38 | if (args.Length > 2 && !int.TryParse(args[1], out s_seed)) 39 | { 40 | PrintUsage(); 41 | return; 42 | } 43 | 44 | ExecuteTestMix(); 45 | } 46 | 47 | public static void PrintUsage() 48 | { 49 | Console.WriteLine("USAGE: stress.run.exe [duration (timespan)] [workerCount (int)] [seed (int)]"); 50 | } 51 | 52 | public static void ExecuteTestMix() 53 | { 54 | Console.WriteLine($"executing stress test mix (duration={s_duration} workercount={s_workerCount} seed={s_seed})"); 55 | 56 | CancellationTokenSource completeSource = new CancellationTokenSource(s_duration); 57 | 58 | var unitTests = new StressTestsAssemblyTestEnumerator().ToArray(); 59 | 60 | var testPattern = new RandomTestPattern(); 61 | 62 | testPattern.Initialize(s_seed, unitTests); 63 | 64 | DedicatedThreadWorkerStrategy workerStrategy = new DedicatedThreadWorkerStrategy(); 65 | 66 | StaticLoadPattern loadPattern = new StaticLoadPattern() { WorkerCount = s_workerCount }; 67 | 68 | loadPattern.Execute(testPattern, workerStrategy, completeSource.Token); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/stress.run/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("stress.run")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("e685e428-1dd2-4329-91bd-68cdb25c1231")] 20 | -------------------------------------------------------------------------------- /src/stress.run/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "Microsoft.NETCore.App": { 4 | "type": "platform", 5 | "version": "1.0.0" 6 | } 7 | }, 8 | "frameworks": { 9 | "netcoreapp1.0": { 10 | "imports": [ 11 | "dnxcore50", 12 | "portable-net45+win8" 13 | ] 14 | } 15 | }, 16 | "runtimes": { 17 | "win": {}, 18 | "win7-x64": {}, 19 | "win7-x86": {}, 20 | "ubuntu.14.04-x64": {}, 21 | "osx.10.10-x64": {}, 22 | "centos.7-x64": {}, 23 | "rhel.7-x64": {}, 24 | "debian.8-x64": {} 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/stress.run/stress.run.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | false 6 | false 7 | Exe 8 | netcoreapp1.0 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/stress.run/stress.run.xproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 10 | e685e428-1dd2-4329-91bd-68cdb25c1231 11 | stress.run 12 | .\obj 13 | .\bin\ 14 | v4.5.2 15 | 16 | 17 | 18 | 2.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/stress.samples/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/stress.samples/Program.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 6 | // 7 | 8 | using stress.execution; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Linq; 12 | using System.Text; 13 | using System.Threading; 14 | using System.Threading.Tasks; 15 | 16 | namespace stress.samples 17 | { 18 | internal class Program 19 | { 20 | private static void Main(string[] args) 21 | { 22 | CancellationTokenSource tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(20)); 23 | 24 | new ConcurrentDictionaryLoadTesting().SimpleLoad(tokenSource.Token); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/stress.samples/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 6 | // 7 | 8 | using System.Reflection; 9 | using System.Runtime.CompilerServices; 10 | using System.Runtime.InteropServices; 11 | 12 | // General Information about an assembly is controlled through the following 13 | // set of attributes. Change these attribute values to modify the information 14 | // associated with an assembly. 15 | [assembly: AssemblyTitle("stress.samples")] 16 | [assembly: AssemblyDescription("")] 17 | [assembly: AssemblyConfiguration("")] 18 | [assembly: AssemblyCompany("")] 19 | [assembly: AssemblyProduct("stress.samples")] 20 | [assembly: AssemblyCopyright("Copyright \u00A9 2015")] 21 | [assembly: AssemblyTrademark("")] 22 | [assembly: AssemblyCulture("")] 23 | 24 | // Setting ComVisible to false makes the types in this assembly not visible 25 | // to COM components. If you need to access a type in this assembly from 26 | // COM, set the ComVisible attribute to true on that type. 27 | [assembly: ComVisible(false)] 28 | 29 | // The following GUID is for the ID of the typelib if this project is exposed to COM 30 | [assembly: Guid("0eed5db1-4bb7-4ec1-bb94-a4f4db0cb252")] 31 | 32 | // Version information for an assembly consists of the following four values: 33 | // 34 | // Major Version 35 | // Minor Version 36 | // Build Number 37 | // Revision 38 | // 39 | // You can specify all the values or you can default the Build and Revision Numbers 40 | // by using the '*' as shown below: 41 | // [assembly: AssemblyVersion("1.0.*")] 42 | [assembly: AssemblyVersion("1.0.0.0")] 43 | [assembly: AssemblyFileVersion("1.0.0.0")] 44 | -------------------------------------------------------------------------------- /src/stress.samples/SimpleSample.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 6 | // 7 | 8 | using stress.execution; 9 | using System; 10 | using System.Collections.Concurrent; 11 | using System.Collections.Generic; 12 | using System.Linq; 13 | using System.Text; 14 | using System.Threading; 15 | using System.Threading.Tasks; 16 | using Xunit; 17 | 18 | namespace stress.samples 19 | { 20 | public class SimpleSample 21 | { 22 | [Load("00:00:20")] 23 | public void SimpleLoad(CancellationToken cancelToken) 24 | { 25 | var unitTests = new UnitTest[] { new UnitTest(this.Foo), new UnitTest(this.Bar), new UnitTest(this.Shz), new UnitTest(this.Nit) }; 26 | 27 | var testPattern = new RandomTestPattern(); 28 | 29 | testPattern.Initialize(0, unitTests); 30 | 31 | var workerStrategy = new DedicatedThreadWorkerStrategy(); 32 | 33 | var loadPattern = new StaticLoadPattern() { WorkerCount = 24 }; 34 | 35 | Task t = loadPattern.ExecuteAsync(testPattern, workerStrategy, cancelToken); 36 | 37 | Task.Delay(3000).GetAwaiter().GetResult(); 38 | 39 | var rootLoadPattern = new StaticLoadPattern() { WorkerCount = 500 }; 40 | 41 | //add a burst of execution 42 | rootLoadPattern.Execute(new UnitTest(Root), workerStrategy, new CancellationTokenSource(10000).Token); 43 | 44 | //wait for original workers to complete 45 | t.GetAwaiter().GetResult(); 46 | } 47 | 48 | public void Foo() 49 | { 50 | Console.WriteLine("Hi I'm Foo :)"); 51 | } 52 | 53 | public void Bar() 54 | { 55 | Console.WriteLine("Hi I'm Bar :|"); 56 | } 57 | 58 | public void Shz() 59 | { 60 | Console.WriteLine("Hi I'm Shz :("); 61 | } 62 | 63 | public void Nit() 64 | { 65 | Console.WriteLine("Hi I'm Nit :$"); 66 | } 67 | 68 | public void Root() 69 | { 70 | Console.WriteLine("Hi I'm Root %"); 71 | } 72 | } 73 | 74 | public class ConcurrentDictionaryLoadTesting 75 | { 76 | [Load("00:00:20")] 77 | public void SimpleLoad(CancellationToken cancelToken) 78 | { 79 | var workerStrategy = new DedicatedThreadWorkerStrategy(); 80 | 81 | var readPattern = new StaticLoadPattern() { WorkerCount = 5 }; 82 | 83 | Task t = readPattern.ExecuteAsync(new UnitTest(ConcurrentRead), workerStrategy, cancelToken); 84 | 85 | var writePattern = new StaticLoadPattern() { WorkerCount = 1 }; 86 | 87 | //add a burst of execution 88 | Task t1 = writePattern.ExecuteAsync(new UnitTest(ConcurrentWrite), workerStrategy, cancelToken); 89 | 90 | //wait for original workers to complete 91 | Task.WaitAll(t, t1); 92 | } 93 | 94 | public void OnlyReaders(CancellationToken cancelToken) 95 | { 96 | var workerStrategy = new DedicatedThreadWorkerStrategy(); 97 | 98 | //setup dictionary 99 | 100 | var readPattern = new StaticLoadPattern() { WorkerCount = 5 }; 101 | 102 | readPattern.ExecuteAsync(new UnitTest(ConcurrentRead), workerStrategy, cancelToken).Wait(); 103 | } 104 | 105 | [Fact] 106 | public void ConcurrentRead() 107 | { 108 | int key = _rand.Next(100); 109 | int val; 110 | 111 | if (!_dictoinary.TryGetValue(key, out val)) 112 | { 113 | val = -1; 114 | } 115 | 116 | Console.WriteLine($"GET: {key} = {val}"); 117 | } 118 | 119 | [Fact] 120 | public void ConcurrentWrite() 121 | { 122 | int key = _rand.Next(100); 123 | int val = _rand.Next(100); 124 | 125 | _dictoinary[key] = val; 126 | Console.WriteLine($"GET: {key} = {val}"); 127 | } 128 | 129 | private ConcurrentDictionary _dictoinary = new ConcurrentDictionary(); 130 | private Random _rand = new Random(); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/stress.samples/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/stress.samples/stress.samples.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {0EED5DB1-4BB7-4EC1-BB94-A4F4DB0CB252} 9 | Exe 10 | Properties 11 | stress.samples 12 | stress.samples 13 | v4.6 14 | 512 15 | true 16 | SAK 17 | SAK 18 | SAK 19 | SAK 20 | 21 | 22 | 23 | 24 | 25 | AnyCPU 26 | true 27 | full 28 | false 29 | bin\Debug\ 30 | DEBUG;TRACE 31 | prompt 32 | 4 33 | 34 | 35 | AnyCPU 36 | pdbonly 37 | true 38 | bin\Release\ 39 | TRACE 40 | prompt 41 | 4 42 | 43 | 44 | 45 | ..\..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll 46 | True 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | ..\..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll 58 | True 59 | 60 | 61 | False 62 | ..\..\..\packages\xunit.assert.2.1.0\lib\dotnet\xunit.assert.dll 63 | True 64 | 65 | 66 | False 67 | ..\..\..\packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll 68 | True 69 | 70 | 71 | False 72 | ..\..\..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll 73 | True 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 92 | 93 | 94 | 95 | 102 | -------------------------------------------------------------------------------- /src/stress.tests/JaggedArray.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Xunit; 6 | 7 | namespace stress.tests 8 | { 9 | public static class JaggedArray 10 | { 11 | private const int EDGEARR_MAXSIZE = 1024; 12 | private const int EDGEARR_MINSIZE = 64; 13 | 14 | private const int INNERARR_MAXSIZE = 128; 15 | private const int INNERARR_MINSIZE = 64; 16 | 17 | private static Random s_rand = new Random(); 18 | 19 | private static object[] s_roots = new object[128]; 20 | 21 | static JaggedArray() 22 | { 23 | for(int i = 0; i < s_roots.Length; i++) 24 | { 25 | s_roots[i] = NextInnerArray(); 26 | } 27 | } 28 | 29 | [Fact] 30 | public static void ReplaceEdge() 31 | { 32 | //pick a random rooted jagged array 33 | var inner = (object[])s_roots[s_rand.Next(s_roots.Length)]; 34 | 35 | //pick a random edge 36 | var edgeIx = s_rand.Next(inner.Length); 37 | 38 | var edge = (ChecksumArray)inner[edgeIx]; 39 | 40 | //replace it and validate it's checksum 41 | inner[edgeIx] = NextEdgeArray(); 42 | 43 | edge.AssertChecksum(); 44 | } 45 | 46 | [Fact] 47 | public static void ReplaceInner() 48 | { 49 | //pick a random rooted jagged array 50 | var innerIx = s_rand.Next(s_roots.Length); 51 | 52 | var inner = (object[])s_roots[innerIx]; 53 | 54 | //replace and validate all the edge array's checksums 55 | s_roots[innerIx] = NextInnerArray(); 56 | 57 | foreach (ChecksumArray edge in inner) 58 | { 59 | edge.AssertChecksum(); 60 | } 61 | } 62 | 63 | private static object[] NextInnerArray() 64 | { 65 | int size = s_rand.Next(INNERARR_MINSIZE, INNERARR_MAXSIZE + 1); 66 | 67 | object[] arr = new object[size]; 68 | 69 | for (int i = 0; i < arr.Length; i++) 70 | { 71 | arr[i] = NextEdgeArray(); 72 | } 73 | 74 | return arr; 75 | } 76 | 77 | private static ChecksumArray NextEdgeArray() 78 | { 79 | int size = s_rand.Next(EDGEARR_MINSIZE, EDGEARR_MAXSIZE + 1); 80 | 81 | return new ChecksumArray(s_rand, size); 82 | } 83 | 84 | 85 | private class ChecksumArray 86 | { 87 | private int _checksum; 88 | private int[] _arr; 89 | 90 | public ChecksumArray(Random rand, int size) 91 | { 92 | _arr = new int[size]; 93 | 94 | for(int i = 0; i < _arr.Length; i++) 95 | { 96 | _arr[i] = rand.Next(int.MinValue, int.MaxValue); 97 | 98 | _checksum ^= _arr[i]; 99 | } 100 | } 101 | 102 | public int AssertChecksum() 103 | { 104 | int chk = 0; 105 | 106 | for (int i = 0; i < _arr.Length; i++) 107 | { 108 | chk ^= _arr[i]; 109 | } 110 | 111 | Assert.Equal(chk, _checksum); 112 | 113 | return _checksum; 114 | } 115 | 116 | public int Checksum { get { return _checksum; } } 117 | } 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/stress.tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("stress.tests")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("22908553-ca78-42a4-8d79-0706750e0467")] 20 | -------------------------------------------------------------------------------- /src/stress.tests/StressTestsAssemblyTestEnumerator.cs: -------------------------------------------------------------------------------- 1 | using stress.execution; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Collections; 9 | 10 | namespace stress.tests 11 | { 12 | public class StressTestsAssemblyTestEnumerator : UnitTestEnumerator 13 | { 14 | protected override IEnumerable GetTests() 15 | { 16 | return new XunitTestClassEnumerator(typeof(JaggedArray)).Concat(new XunitTestClassEnumerator(typeof(ArrayTests))); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/stress.tests/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "NETStandard.Library": "1.6.1", 4 | "System.Diagnostics.Process": "4.3.0", 5 | "xunit.core": "2.2.0", 6 | "xunit.assert": "2.2.0" 7 | }, 8 | "frameworks": { 9 | "netstandard1.3": { 10 | "imports": "portable-net45+win8" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/stress.tests/stress.tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 14.0 7 | Debug 8 | AnyCPU 9 | {D6F0FF51-AFDA-4D01-A052-E1889861ECFB} 10 | Library 11 | Properties 12 | stress.tests 13 | stress.tests 14 | en-US 15 | 512 16 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | v5.0 18 | 19 | 20 | false 21 | .NETPortable 22 | SAK 23 | SAK 24 | SAK 25 | SAK 26 | 27 | 28 | true 29 | full 30 | false 31 | DEBUG;TRACE 32 | prompt 33 | 4 34 | true 35 | 36 | 37 | 38 | 39 | pdbonly 40 | true 41 | TRACE 42 | prompt 43 | 4 44 | true 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | {7E1E57D9-8587-4EA1-86F7-02813819B118} 61 | stress.execution 62 | 63 | 64 | 65 | 66 | 73 | -------------------------------------------------------------------------------- /src/stress/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/stress/Program.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | #pragma warning disable 3016 6 | 7 | using stress.codegen; 8 | using stress.execution; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Linq; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | 15 | namespace stress.console 16 | { 17 | internal class Program 18 | { 19 | private static void Main(string[] args) 20 | { 21 | MultiFunctionCmdArgs argParser = new MultiFunctionCmdArgs(); 22 | 23 | argParser.AddFunction("createsuite", GenTests); 24 | 25 | argParser.InvokeFunctionWithArgs(args); 26 | } 27 | 28 | public static int GenTests(GenTestsArgs args) 29 | { 30 | LoadSuiteGenerator suiteGen = new LoadSuiteGenerator(); 31 | 32 | int seed = args.Seed == 0 ? new Random().Next() : args.Seed; 33 | 34 | suiteGen.GenerateSuite(seed, args.SuiteName, args.OutputPath, args.TestPaths, args.FileMasks, args.HintPaths, LoadSuiteConfig.Deserialize(args.ConfigPath)); 35 | 36 | return 0; 37 | } 38 | } 39 | 40 | internal class GenTestsArgs : CmdArgsBase 41 | { 42 | [CmdArg(typeof(string), "n", "name", Required = true, ValueMoniker = "suite_name", Description = "Path to the json test template file describing the tests to be generated")] 43 | public string SuiteName { get; set; } 44 | 45 | [CmdArg(typeof(string), "c", "config", Required = true, ValueMoniker = "config_path", Description = "Path to the json load suite config file describing the tests to be generated")] 46 | public string ConfigPath { get; set; } 47 | 48 | [CmdArg(typeof(string), "o", "output", Required = true, ValueMoniker = "output_path", Description = "Path to the directory in which all generated tests will be placed")] 49 | public string OutputPath { get; set; } 50 | 51 | [CmdArg(typeof(string[]), "t", "testpaths", Required = true, ValueMoniker = "test_path[;test_pathN...]", Description = "Semicolon separated list of paths to test binaries")] 52 | public string[] TestPaths { get; set; } 53 | 54 | [CmdArg(typeof(string[]), "f", "filemasks", Required = false, Default = new string[] { "*.dll" }, ValueMoniker = "filemask[;filemaskN...]", Description = "Semicolon separated list of file search strings for test binaries")] 55 | public string[] FileMasks { get; set; } 56 | 57 | [CmdArg(typeof(string[]), "h", "hintpaths", Required = false, Default = new string[] { }, ValueMoniker = "hintpath[;hintpathN...]", Description = "Semicolon separated list of hint paths for test binary references")] 58 | public string[] HintPaths { get; set; } 59 | 60 | [CmdArg(typeof(int), "s", "seed", Required = false, ValueMoniker = "suite_seed", Description = "The seed used when randomly seleting unite tests for generated load tests")] 61 | public int Seed { get; set; } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/stress/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | // 4 | 5 | using System.Reflection; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | 9 | // General Information about an assembly is controlled through the following 10 | // set of attributes. Change these attribute values to modify the information 11 | // associated with an assembly. 12 | [assembly: AssemblyTitle("stress")] 13 | [assembly: AssemblyDescription("")] 14 | [assembly: AssemblyConfiguration("")] 15 | [assembly: AssemblyCompany("")] 16 | [assembly: AssemblyProduct("stress")] 17 | [assembly: AssemblyCopyright("Copyright \u00A9 2015")] 18 | [assembly: AssemblyTrademark("")] 19 | [assembly: AssemblyCulture("")] 20 | 21 | // Setting ComVisible to false makes the types in this assembly not visible 22 | // to COM components. If you need to access a type in this assembly from 23 | // COM, set the ComVisible attribute to true on that type. 24 | [assembly: ComVisible(false)] 25 | 26 | // The following GUID is for the ID of the typelib if this project is exposed to COM 27 | [assembly: Guid("c25a3d15-a367-4607-9df9-7a1d230ff6f0")] 28 | 29 | // Version information for an assembly consists of the following four values: 30 | // 31 | // Major Version 32 | // Minor Version 33 | // Build Number 34 | // Revision 35 | // 36 | // You can specify all the values or you can default the Build and Revision Numbers 37 | // by using the '*' as shown below: 38 | // [assembly: AssemblyVersion("1.0.*")] 39 | [assembly: AssemblyVersion("1.0.0.0")] 40 | [assembly: AssemblyFileVersion("1.0.0.0")] 41 | -------------------------------------------------------------------------------- /src/stress/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/stress/stress.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {C25A3D15-A367-4607-9DF9-7A1D230FF6F0} 9 | Exe 10 | Properties 11 | stress.console 12 | stress 13 | 512 14 | true 15 | SAK 16 | SAK 17 | SAK 18 | SAK 19 | 20 | 21 | .NETFramework 22 | v4.5 23 | 24 | 25 | AnyCPU 26 | true 27 | full 28 | false 29 | DEBUG;TRACE 30 | prompt 31 | 4 32 | 33 | 34 | AnyCPU 35 | pdbonly 36 | true 37 | TRACE 38 | prompt 39 | 4 40 | 41 | 42 | 43 | 44 | ..\..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll 45 | True 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | ..\..\packages\xunit.abstractions\2.0.0\lib\net35\xunit.abstractions.dll 58 | True 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | {b60a62ba-77b2-49fa-94b8-cffd2c3f5825} 73 | stress.codegen 74 | 75 | 76 | 77 | 78 | {7e1e57d9-8587-4ea1-86f7-02813819b118} 79 | stress.execution 80 | 81 | 82 | 83 | 84 | 85 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 86 | 87 | 88 | 89 | 96 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # Stress Test Generation # 2 | 3 | msbuild genstress.proj /p:UnitTestDirectory= 4 | 5 | ## Properties ## 6 | -------------------------------------------------------------------------------- /test/buildgen.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | $(MSBuildThisFileDirectory)generated/ 6 | $(GeneratedRootPath) 7 | $(SuitePath) 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | RestorePackages; 22 | $(TraversalBuildDependsOn); 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /test/buildgenerated.proj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/dotnet-reliability/6addc13cfb3c4333733e787c0c06d53921398acb/test/buildgenerated.proj -------------------------------------------------------------------------------- /test/dir.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | netcoreapp1.0 7 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/dir.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | 5 | 6 | 7 | .NETCoreApp,Version=v1.0 8 | 9 | 10 | 11 | 12 | 14 | 16 | 17 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | UpdateImportedProjectRelativePaths;$(CoreBuildDependsOn) 27 | UpdateImportedProjectRelativePaths;$(CoreCleanDependsOn) 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /test/suiteconfig/16hr.suite.json: -------------------------------------------------------------------------------- 1 | { 2 | "Host": "corerun", 3 | "LoadTestConfigs": [ 4 | { 5 | "TestCount": 4, 6 | "NumTests": 100, 7 | "Duration": "16:00:00", 8 | "NumWorkers": 8, 9 | "TestPattern": "stress.execution.RandomTestPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 10 | "LoadPattern": "stress.execution.StaticLoadPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 11 | "WorkerStrategy": "stress.execution.DedicatedThreadWorkerStrategy, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 12 | "EnvironmentVariables": { 13 | "COMPlus_DebugBreakOnAssert": "1", 14 | "COMPlus_AssertOnFailFast": "1", 15 | "COMPlus_StressLog": "1", 16 | "COMPlus_StressLogSize": "2097152" 17 | } 18 | }, 19 | { 20 | "TestCount": 4, 21 | "NumTests": 100, 22 | "Duration": "16:00:00", 23 | "NumWorkers": 8, 24 | "TestPattern": "stress.execution.RandomTestPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 25 | "LoadPattern": "stress.execution.StaticLoadPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 26 | "WorkerStrategy": "stress.execution.DedicatedThreadWorkerStrategy, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 27 | "EnvironmentVariables": { 28 | "COMPlus_DebugBreakOnAssert": "1", 29 | "COMPlus_AssertOnFailFast": "1", 30 | "COMPlus_GCStress": "3", 31 | "COMPlus_HeapVerify": "1", 32 | "COMPlus_StressLog": "1", 33 | "COMPlus_StressLogSize": "2097152" 34 | } 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /test/suiteconfig/1hr.suite.json: -------------------------------------------------------------------------------- 1 | { 2 | "Host": "corerun", 3 | "LoadTestConfigs": [ 4 | { 5 | "TestCount": 64, 6 | "NumTests": 10, 7 | "Duration": "01:00:00", 8 | "NumWorkers": 8, 9 | "TestPattern": "stress.execution.RandomTestPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 10 | "LoadPattern": "stress.execution.StaticLoadPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 11 | "WorkerStrategy": "stress.execution.DedicatedThreadWorkerStrategy, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 12 | "EnvironmentVariables": { 13 | "COMPlus_DebugBreakOnAssert": "1", 14 | "COMPlus_AssertOnFailFast": "1", 15 | "COMPlus_StressLog": "1", 16 | "COMPlus_StressLogSize": "2097152" 17 | } 18 | }, 19 | { 20 | "TestCount": 64, 21 | "NumTests": 10, 22 | "Duration": "01:00:00", 23 | "NumWorkers": 8, 24 | "TestPattern": "stress.execution.RandomTestPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 25 | "LoadPattern": "stress.execution.StaticLoadPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 26 | "WorkerStrategy": "stress.execution.DedicatedThreadWorkerStrategy, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 27 | "EnvironmentVariables": { 28 | "COMPlus_DebugBreakOnAssert": "1", 29 | "COMPlus_AssertOnFailFast": "1", 30 | "COMPlus_GCStress": "3", 31 | "COMPlus_HeapVerify": "1", 32 | "COMPlus_StressLog": "1", 33 | "COMPlus_StressLogSize": "2097152" 34 | } 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /test/suiteconfig/2hr.suite.json: -------------------------------------------------------------------------------- 1 | { 2 | "Host": "corerun", 3 | "LoadTestConfigs": [ 4 | { 5 | "TestCount": 32, 6 | "NumTests": 20, 7 | "Duration": "02:00:00", 8 | "NumWorkers": 8, 9 | "TestPattern": "stress.execution.RandomTestPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 10 | "LoadPattern": "stress.execution.StaticLoadPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 11 | "WorkerStrategy": "stress.execution.DedicatedThreadWorkerStrategy, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 12 | "EnvironmentVariables": { 13 | "COMPlus_DebugBreakOnAssert": "1", 14 | "COMPlus_AssertOnFailFast": "1", 15 | "COMPlus_StressLog": "1", 16 | "COMPlus_StressLogSize": "2097152" 17 | } 18 | }, 19 | { 20 | "TestCount": 32, 21 | "NumTests": 20, 22 | "Duration": "02:00:00", 23 | "NumWorkers": 8, 24 | "TestPattern": "stress.execution.RandomTestPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 25 | "LoadPattern": "stress.execution.StaticLoadPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 26 | "WorkerStrategy": "stress.execution.DedicatedThreadWorkerStrategy, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 27 | "EnvironmentVariables": { 28 | "COMPlus_DebugBreakOnAssert": "1", 29 | "COMPlus_AssertOnFailFast": "1", 30 | "COMPlus_GCStress": "3", 31 | "COMPlus_HeapVerify": "1", 32 | "COMPlus_StressLog": "1", 33 | "COMPlus_StressLogSize": "2097152" 34 | } 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /test/suiteconfig/4hr.suite.json: -------------------------------------------------------------------------------- 1 | { 2 | "Host": "corerun", 3 | "LoadTestConfigs": [ 4 | { 5 | "TestCount": 16, 6 | "NumTests": 50, 7 | "Duration": "04:00:00", 8 | "NumWorkers": 8, 9 | "TestPattern": "stress.execution.RandomTestPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 10 | "LoadPattern": "stress.execution.StaticLoadPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 11 | "WorkerStrategy": "stress.execution.DedicatedThreadWorkerStrategy, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 12 | "EnvironmentVariables": { 13 | "COMPlus_DebugBreakOnAssert": "1", 14 | "COMPlus_AssertOnFailFast": "1", 15 | "COMPlus_StressLog": "1", 16 | "COMPlus_StressLogSize": "2097152" 17 | } 18 | }, 19 | { 20 | "TestCount": 16, 21 | "NumTests": 50, 22 | "Duration": "04:00:00", 23 | "NumWorkers": 8, 24 | "TestPattern": "stress.execution.RandomTestPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 25 | "LoadPattern": "stress.execution.StaticLoadPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 26 | "WorkerStrategy": "stress.execution.DedicatedThreadWorkerStrategy, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 27 | "EnvironmentVariables": { 28 | "COMPlus_DebugBreakOnAssert": "1", 29 | "COMPlus_AssertOnFailFast": "1", 30 | "COMPlus_GCStress": "3", 31 | "COMPlus_HeapVerify": "1", 32 | "COMPlus_StressLog": "1", 33 | "COMPlus_StressLogSize": "2097152" 34 | } 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /test/suiteconfig/8hr.suite.json: -------------------------------------------------------------------------------- 1 | { 2 | "Host": "corerun", 3 | "LoadTestConfigs": [ 4 | { 5 | "TestCount": 8, 6 | "NumTests": 50, 7 | "Duration": "08:00:00", 8 | "NumWorkers": 8, 9 | "TestPattern": "stress.execution.RandomTestPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 10 | "LoadPattern": "stress.execution.StaticLoadPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 11 | "WorkerStrategy": "stress.execution.DedicatedThreadWorkerStrategy, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 12 | "EnvironmentVariables": { 13 | "COMPlus_DebugBreakOnAssert": "1", 14 | "COMPlus_AssertOnFailFast": "1", 15 | "COMPlus_StressLog": "1", 16 | "COMPlus_StressLogSize": "2097152" 17 | } 18 | }, 19 | { 20 | "TestCount": 8, 21 | "NumTests": 50, 22 | "Duration": "08:00:00", 23 | "NumWorkers": 8, 24 | "TestPattern": "stress.execution.RandomTestPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 25 | "LoadPattern": "stress.execution.StaticLoadPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 26 | "WorkerStrategy": "stress.execution.DedicatedThreadWorkerStrategy, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 27 | "EnvironmentVariables": { 28 | "COMPlus_DebugBreakOnAssert": "1", 29 | "COMPlus_AssertOnFailFast": "1", 30 | "COMPlus_GCStress": "3", 31 | "COMPlus_HeapVerify": "1", 32 | "COMPlus_StressLog": "1", 33 | "COMPlus_StressLogSize": "2097152" 34 | } 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /test/suiteconfig/smoketest.suite.json: -------------------------------------------------------------------------------- 1 | { 2 | "Host": "corerun", 3 | "LoadTestConfigs": [ 4 | { 5 | "TestCount": 10, 6 | "NumTests": 10, 7 | "Duration": "00:01:30", 8 | "NumWorkers": 8, 9 | "TestPattern": "stress.execution.RandomTestPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 10 | "LoadPattern": "stress.execution.StaticLoadPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 11 | "WorkerStrategy": "stress.execution.DedicatedThreadWorkerStrategy, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 12 | "EnvironmentVariables": { 13 | "COMPlus_DebugBreakOnAssert": "1", 14 | "COMPlus_AssertOnFailFast": "1" 15 | } 16 | }, 17 | { 18 | "TestCount": 10, 19 | "NumTests": 10, 20 | "Duration": "00:01:30", 21 | "NumWorkers": 8, 22 | "TestPattern": "stress.execution.RandomTestPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 23 | "LoadPattern": "stress.execution.StaticLoadPattern, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 24 | "WorkerStrategy": "stress.execution.DedicatedThreadWorkerStrategy, stress.execution, Version=1.0.0, Culture=neutral, PublicKeyToken=null", 25 | "SelfDestruct": true, 26 | "EnvironmentVariables": { 27 | "COMPlus_DebugBreakOnAssert": "1", 28 | "COMPlus_AssertOnFailFast": "1" 29 | } 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /toolbox/list_build_ids/DumpCore.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DumpCore", "DumpCore.vcxproj", "{610DBC31-2C3C-4E5C-A2CC-8E8FA41BC46A}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|ARM = Release|ARM 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {610DBC31-2C3C-4E5C-A2CC-8E8FA41BC46A}.Debug|ARM.ActiveCfg = Debug|ARM 19 | {610DBC31-2C3C-4E5C-A2CC-8E8FA41BC46A}.Debug|ARM.Build.0 = Debug|ARM 20 | {610DBC31-2C3C-4E5C-A2CC-8E8FA41BC46A}.Debug|x64.ActiveCfg = Debug|x64 21 | {610DBC31-2C3C-4E5C-A2CC-8E8FA41BC46A}.Debug|x64.Build.0 = Debug|x64 22 | {610DBC31-2C3C-4E5C-A2CC-8E8FA41BC46A}.Debug|x86.ActiveCfg = Debug|x86 23 | {610DBC31-2C3C-4E5C-A2CC-8E8FA41BC46A}.Debug|x86.Build.0 = Debug|x86 24 | {610DBC31-2C3C-4E5C-A2CC-8E8FA41BC46A}.Release|ARM.ActiveCfg = Release|ARM 25 | {610DBC31-2C3C-4E5C-A2CC-8E8FA41BC46A}.Release|ARM.Build.0 = Release|ARM 26 | {610DBC31-2C3C-4E5C-A2CC-8E8FA41BC46A}.Release|x64.ActiveCfg = Release|x64 27 | {610DBC31-2C3C-4E5C-A2CC-8E8FA41BC46A}.Release|x64.Build.0 = Release|x64 28 | {610DBC31-2C3C-4E5C-A2CC-8E8FA41BC46A}.Release|x86.ActiveCfg = Release|x86 29 | {610DBC31-2C3C-4E5C-A2CC-8E8FA41BC46A}.Release|x86.Build.0 = Release|x86 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /toolbox/list_build_ids/DumpCore.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | ARM 7 | 8 | 9 | Release 10 | ARM 11 | 12 | 13 | Debug 14 | x86 15 | 16 | 17 | Release 18 | x86 19 | 20 | 21 | Debug 22 | x64 23 | 24 | 25 | Release 26 | x64 27 | 28 | 29 | 30 | {610dbc31-2c3c-4e5c-a2cc-8e8fa41bc46a} 31 | Linux 32 | DumpCore 33 | 14.0 34 | Linux 35 | 1.0 36 | Generic 37 | {D51BCBC9-82E9-4017-911E-C93873C4EA2B} 38 | 39 | 40 | 41 | true 42 | 43 | 44 | false 45 | 46 | 47 | true 48 | 49 | 50 | false 51 | 52 | 53 | true 54 | 55 | 56 | false 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | C:\python27\include;D:\work\linux_headers;$(IncludePath);$(ISenseIncludePath) 65 | 66 | 67 | D:\work\linux_headers;$(IncludePath);$(ISenseIncludePath) 68 | 69 | 70 | 71 | 72 | true 73 | 74 | 75 | 76 | 77 | true 78 | 79 | 80 | true 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /toolbox/list_build_ids/example.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | from _core_dump import read_core_dump 3 | 4 | build_ids, modules_missing_build_ids = read_core_dump(argv[1]) 5 | 6 | print("Modules:") 7 | for module, id in build_ids: 8 | print(" %s %s", id, module) 9 | 10 | print() 11 | print("Modules without build ids:") 12 | for module in modules_missing_build_ids: 13 | print(" " + module); 14 | -------------------------------------------------------------------------------- /toolbox/list_build_ids/python_binding.cpp: -------------------------------------------------------------------------------- 1 | #include "Python.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | extern std::set encountered_modules; 8 | extern std::map module_build_ids; 9 | extern int walk_core_dump(const char *path); 10 | 11 | extern "C" 12 | PyObject *read_core_dump(PyObject *self, PyObject *args) 13 | { 14 | if (!PyString_Check(args)) 15 | { 16 | PyErr_SetString(PyExc_TypeError, "read_core_dump requires a full path as only argument."); 17 | return NULL; 18 | } 19 | 20 | const char *path = PyString_AsString(args); 21 | int core_result = walk_core_dump(path); 22 | if (core_result != 0) 23 | { 24 | PyErr_SetString(PyExc_Exception, "Error walking core dump."); 25 | return NULL; 26 | } 27 | 28 | // Fill the build id list. 29 | PyObject *build_ids = PyList_New(0); 30 | for (std::map::iterator itr = module_build_ids.begin(); itr != module_build_ids.end(); ++itr) 31 | { 32 | PyObject *tmp = Py_BuildValue("(ss)", itr->first.c_str(), itr->second.c_str()); 33 | PyList_Append(build_ids, tmp); 34 | Py_DECREF(tmp); 35 | } 36 | 37 | // Fill the no id list. 38 | PyObject *no_id = PyList_New(0); 39 | for (std::set::iterator itr = encountered_modules.begin(); itr != encountered_modules.end(); ++itr) 40 | { 41 | if (module_build_ids.find(*itr) == module_build_ids.end()) 42 | { 43 | PyObject *tmp = Py_BuildValue("s", itr->c_str()); 44 | PyList_Append(no_id, tmp); 45 | Py_DECREF(tmp); 46 | } 47 | } 48 | 49 | // return a tuple of these two 50 | PyObject *result = Py_BuildValue("(OO)", build_ids, no_id); 51 | Py_DECREF(build_ids); 52 | Py_DECREF(no_id); 53 | 54 | return result; 55 | } 56 | 57 | 58 | extern "C" 59 | PyMethodDef module_methods[] = 60 | { 61 | { "read_core_dump", (PyCFunction)read_core_dump, METH_O, NULL }, 62 | { NULL, NULL, 0, NULL } 63 | }; 64 | 65 | PyObject *s_module = NULL; 66 | 67 | extern "C" 68 | PyMODINIT_FUNC init_core_dump(void) 69 | { 70 | s_module = Py_InitModule("_core_dump", module_methods); 71 | } 72 | -------------------------------------------------------------------------------- /toolbox/list_build_ids/setup.py: -------------------------------------------------------------------------------- 1 | # sudo apt-get install python-dev 2 | # python setup.py build_ext --inplace 3 | 4 | from distutils.core import setup, Extension 5 | 6 | setup(ext_modules=[Extension("_core_dump", ["python_binding.cpp", "list_build_ids.cpp"])]) 7 | --------------------------------------------------------------------------------