зеркало из https://github.com/dotnet/aspnetcore.git
Downgrade stable package versions and remove duplicate test project (#3991)
This commit is contained in:
Родитель
1f19f1a51a
Коммит
4b4bd68fc7
|
@ -2,11 +2,12 @@
|
|||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
</PropertyGroup>
|
||||
<!-- These versions are pinned for backwards compatibility tests. -->
|
||||
<PropertyGroup Label="Package Versions: Pinned">
|
||||
<MicrosoftAspNetCoreAspNetCoreModuleStablePackageVersion>2.2.0-rtm-35665</MicrosoftAspNetCoreAspNetCoreModuleStablePackageVersion>
|
||||
<MicrosoftAspNetCoreAspNetCoreModuleV2StablePackageVersion>2.2.0-rtm-35665</MicrosoftAspNetCoreAspNetCoreModuleV2StablePackageVersion>
|
||||
<MicrosoftAspNetCoreServerIISStablePackageVersion>2.2.0-rtm-35665</MicrosoftAspNetCoreServerIISStablePackageVersion>
|
||||
<!-- The AspNetCoreModule package versions are pinned to an older version for forwards and backwards compatibility tests. -->
|
||||
<MicrosoftAspNetCoreAspNetCoreModuleStablePackageVersion>2.2.0-preview3-35497</MicrosoftAspNetCoreAspNetCoreModuleStablePackageVersion>
|
||||
<MicrosoftAspNetCoreAspNetCoreModuleV2StablePackageVersion>2.2.0-preview3-35497</MicrosoftAspNetCoreAspNetCoreModuleV2StablePackageVersion>
|
||||
<MicrosoftAspNetCoreServerIISStablePackageVersion>2.2.0-preview3-35497</MicrosoftAspNetCoreServerIISStablePackageVersion>
|
||||
<!-- These package versions are pinned to 2.1 to create builds for functions -->
|
||||
<MicrosoftAspNetCoreAuthenticationCore21PackageVersion>2.1.0</MicrosoftAspNetCoreAuthenticationCore21PackageVersion>
|
||||
<MicrosoftAspNetCoreConnectionsAbstractions21PackageVersion>2.1.0</MicrosoftAspNetCoreConnectionsAbstractions21PackageVersion>
|
||||
<MicrosoftAspNetCoreHostingAbstractions21PackageVersion>2.1.0</MicrosoftAspNetCoreHostingAbstractions21PackageVersion>
|
||||
|
|
|
@ -1,740 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
IIS configuration sections.
|
||||
|
||||
For schema documentation, see
|
||||
%windir%\system32\inetsrv\config\schema\IIS_schema.xml.
|
||||
|
||||
Please make a backup of this file before making any changes to it.
|
||||
|
||||
-->
|
||||
|
||||
<configuration>
|
||||
|
||||
<!--
|
||||
|
||||
The <configSections> section controls the registration of sections.
|
||||
Section is the basic unit of deployment, locking, searching and
|
||||
containment for configuration settings.
|
||||
|
||||
Every section belongs to one section group.
|
||||
A section group is a container of logically-related sections.
|
||||
|
||||
Sections cannot be nested.
|
||||
Section groups may be nested.
|
||||
|
||||
<section
|
||||
name="" [Required, Collection Key] [XML name of the section]
|
||||
allowDefinition="Everywhere" [MachineOnly|MachineToApplication|AppHostOnly|Everywhere] [Level where it can be set]
|
||||
overrideModeDefault="Allow" [Allow|Deny] [Default delegation mode]
|
||||
allowLocation="true" [true|false] [Allowed in location tags]
|
||||
/>
|
||||
|
||||
The recommended way to unlock sections is by using a location tag:
|
||||
<location path="Default Web Site" overrideMode="Allow">
|
||||
<system.webServer>
|
||||
<asp />
|
||||
</system.webServer>
|
||||
</location>
|
||||
|
||||
-->
|
||||
<configSections>
|
||||
<sectionGroup name="system.applicationHost">
|
||||
<section name="applicationPools" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="configHistory" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="customMetadata" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="listenerAdapters" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="log" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="serviceAutoStartProviders" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="sites" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="webLimits" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
|
||||
<sectionGroup name="system.webServer">
|
||||
<section name="asp" overrideModeDefault="Deny" />
|
||||
<section name="caching" overrideModeDefault="Allow" />
|
||||
<section name="cgi" overrideModeDefault="Deny" />
|
||||
<section name="defaultDocument" overrideModeDefault="Allow" />
|
||||
<section name="directoryBrowse" overrideModeDefault="Allow" />
|
||||
<section name="fastCgi" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="globalModules" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="handlers" overrideModeDefault="Deny" />
|
||||
<section name="httpCompression" overrideModeDefault="Allow" />
|
||||
<section name="httpErrors" overrideModeDefault="Allow" />
|
||||
<section name="httpLogging" overrideModeDefault="Deny" />
|
||||
<section name="httpProtocol" overrideModeDefault="Allow" />
|
||||
<section name="httpRedirect" overrideModeDefault="Allow" />
|
||||
<section name="httpTracing" overrideModeDefault="Deny" />
|
||||
<section name="isapiFilters" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
|
||||
<section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
|
||||
<section name="odbcLogging" overrideModeDefault="Deny" />
|
||||
<sectionGroup name="security">
|
||||
<section name="access" overrideModeDefault="Deny" />
|
||||
<section name="applicationDependencies" overrideModeDefault="Deny" />
|
||||
<sectionGroup name="authentication">
|
||||
<section name="anonymousAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="basicAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="clientCertificateMappingAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="digestAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="iisClientCertificateMappingAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="windowsAuthentication" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
<section name="authorization" overrideModeDefault="Allow" />
|
||||
<section name="ipSecurity" overrideModeDefault="Deny" />
|
||||
<section name="dynamicIpSecurity" overrideModeDefault="Deny" />
|
||||
<section name="isapiCgiRestriction" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="requestFiltering" overrideModeDefault="Allow" />
|
||||
</sectionGroup>
|
||||
<section name="serverRuntime" overrideModeDefault="Deny" />
|
||||
<section name="serverSideInclude" overrideModeDefault="Deny" />
|
||||
<section name="staticContent" overrideModeDefault="Allow" />
|
||||
<sectionGroup name="tracing">
|
||||
<section name="traceFailedRequests" overrideModeDefault="Allow" />
|
||||
<section name="traceProviderDefinitions" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
<section name="urlCompression" overrideModeDefault="Allow" />
|
||||
<section name="validation" overrideModeDefault="Allow" />
|
||||
<sectionGroup name="webdav">
|
||||
<section name="globalSettings" overrideModeDefault="Deny" />
|
||||
<section name="authoring" overrideModeDefault="Deny" />
|
||||
<section name="authoringRules" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
<section name="webSocket" overrideModeDefault="Deny" />
|
||||
<section name="aspNetCore" overrideModeDefault="Allow" />
|
||||
</sectionGroup>
|
||||
<sectionGroup name="system.ftpServer">
|
||||
<section name="log" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||
<section name="firewallSupport" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||
<section name="caching" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||
<section name="providerDefinitions" overrideModeDefault="Deny" />
|
||||
<sectionGroup name="security">
|
||||
<section name="ipSecurity" overrideModeDefault="Deny" />
|
||||
<section name="requestFiltering" overrideModeDefault="Deny" />
|
||||
<section name="authorization" overrideModeDefault="Deny" />
|
||||
<section name="authentication" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
<section name="serverRuntime" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<configProtectedData>
|
||||
<providers>
|
||||
<add name="IISWASOnlyRsaProvider" type="" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useMachineContainer="true" useOAEP="false" />
|
||||
<add name="IISCngProvider" type="Microsoft.ApplicationHost.CngProtectedConfigurationProvider" description="Uses Win32 Crypto CNG to encrypt and decrypt" keyContainerName="iisCngConfigurationKey" useMachineContainer="true" />
|
||||
<add name="IISWASOnlyCngProvider" type="Microsoft.ApplicationHost.CngProtectedConfigurationProvider" description="(WAS Only) Uses Win32 Crypto CNG to encrypt and decrypt" keyContainerName="iisCngWasKey" useMachineContainer="true" />
|
||||
<add name="AesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisConfigurationKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAAX3F7JKrgomyurjp+EzqF/rH26sw4/Bl57PAr0ZDqQJWRVT5LLg2T+nvdVUl0mbFYl2D9zwOqBWPEU29RgmvWDvGqNu6q/qDnRJ/pP/sDbArVJTnK/JQCJ9FuImmu6pz/Xbvq+aGG7FGxlZWOwMGYlnJBkDAseyOWTL8dYsGZ4xXo18NWaIJoimCKPqxUQCKf/arDeIopmx4QSLu9scbgYNHLdv8+pegkLVt5BdhR/xNTU6gb/eIemjy2SCYXASu/6M5Jki0plXyIvHf8Q+kwGSIkPvnCiUnE66koKA4dQ45rG4Ftb4wZ0gSa4bQVp6D6Svhu7fV7rOzBNdNreGF8qA==" />
|
||||
<add name="IISWASOnlyAesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAAbu3YiDQwroP3yTqKR0m1fxXM6E9EBOZ5ZOg7LO1TJwYXCgQTB0hrm1TRAOxFhlPKtok3YVAyYMfazt7GXJ0O447FFg0abNIy4U/PZV/10evK5XvcoUy2qgddsa1EwOI7dqIrhe9T0A9+QtnHpYOqEFUhLj3ZGmhWsvyVBaenBGLWRuZ65Qwtd75/Hc2FcRaYpuDChjrz0OR/x8LKnGGkNMDwe3Ew9MIyImp8AjCGfGBTkevXqlmTOXfBHtWRsbQYlipz1jINc9EXGiPmIRPmLo4MnmQ/48jssL8QI91BRbL62kuQTxPwCZ+v0WzC3C+poF29V3CwjgydcrV5nZq/kw==" />
|
||||
</providers>
|
||||
</configProtectedData>
|
||||
|
||||
<system.applicationHost>
|
||||
|
||||
<applicationPools>
|
||||
<add name="DefaultAppPool" autoStart="true" startMode="AlwaysRunning">
|
||||
<processModel identityType="LocalSystem" />
|
||||
</add>
|
||||
<applicationPoolDefaults managedRuntimeVersion="v4.0">
|
||||
<processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="false" />
|
||||
</applicationPoolDefaults>
|
||||
</applicationPools>
|
||||
|
||||
<!--
|
||||
|
||||
The <customMetadata> section is used internally by the Admin Base Objects
|
||||
(ABO) Compatibility component. Please do not modify its content.
|
||||
|
||||
-->
|
||||
<customMetadata />
|
||||
|
||||
<!--
|
||||
|
||||
The <listenerAdapters> section defines the protocols with which the
|
||||
Windows Process Activation Service (WAS) binds.
|
||||
|
||||
-->
|
||||
<listenerAdapters>
|
||||
<add name="http" />
|
||||
</listenerAdapters>
|
||||
|
||||
<log>
|
||||
<centralBinaryLogFile enabled="true" directory="%SystemDrive%\inetpub\logs\LogFiles" />
|
||||
<centralW3CLogFile enabled="true" directory="%SystemDrive%\inetpub\logs\LogFiles" />
|
||||
</log>
|
||||
|
||||
<sites>
|
||||
<site name="Default Web Site" id="1">
|
||||
<application path="/">
|
||||
<virtualDirectory path="/" physicalPath="%SystemDrive%\inetpub\wwwroot" />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation="*:80:" />
|
||||
</bindings>
|
||||
</site>
|
||||
<siteDefaults>
|
||||
<logFile logFormat="W3C" directory="%SystemDrive%\inetpub\logs\LogFiles" />
|
||||
<traceFailedRequestsLogging directory="%SystemDrive%\inetpub\logs\FailedReqLogFiles" />
|
||||
</siteDefaults>
|
||||
<applicationDefaults applicationPool="DefaultAppPool" />
|
||||
<virtualDirectoryDefaults allowSubDirConfig="true" />
|
||||
</sites>
|
||||
|
||||
<webLimits />
|
||||
|
||||
</system.applicationHost>
|
||||
|
||||
<system.webServer>
|
||||
|
||||
<asp />
|
||||
|
||||
<caching enabled="true" enableKernelCache="true">
|
||||
</caching>
|
||||
|
||||
<cgi />
|
||||
|
||||
<defaultDocument enabled="true">
|
||||
<files>
|
||||
<add value="Default.htm" />
|
||||
<add value="Default.asp" />
|
||||
<add value="index.htm" />
|
||||
<add value="index.html" />
|
||||
<add value="iisstart.htm" />
|
||||
</files>
|
||||
</defaultDocument>
|
||||
|
||||
<directoryBrowse enabled="false" />
|
||||
|
||||
<fastCgi />
|
||||
|
||||
<!--
|
||||
|
||||
The <globalModules> section defines all native-code modules.
|
||||
To enable a module, specify it in the <modules> section.
|
||||
|
||||
-->
|
||||
<globalModules>
|
||||
<add name="HttpLoggingModule" image="%windir%\System32\inetsrv\loghttp.dll" />
|
||||
<add name="UriCacheModule" image="%windir%\System32\inetsrv\cachuri.dll" />
|
||||
<add name="FileCacheModule" image="%windir%\System32\inetsrv\cachfile.dll" />
|
||||
<add name="TokenCacheModule" image="%windir%\System32\inetsrv\cachtokn.dll" />
|
||||
<add name="HttpCacheModule" image="%windir%\System32\inetsrv\cachhttp.dll" />
|
||||
<add name="StaticCompressionModule" image="%windir%\System32\inetsrv\compstat.dll" />
|
||||
<add name="DefaultDocumentModule" image="%windir%\System32\inetsrv\defdoc.dll" />
|
||||
<add name="DirectoryListingModule" image="%windir%\System32\inetsrv\dirlist.dll" />
|
||||
<add name="ProtocolSupportModule" image="%windir%\System32\inetsrv\protsup.dll" />
|
||||
<add name="StaticFileModule" image="%windir%\System32\inetsrv\static.dll" />
|
||||
<add name="AnonymousAuthenticationModule" image="%windir%\System32\inetsrv\authanon.dll" />
|
||||
<add name="RequestFilteringModule" image="%windir%\System32\inetsrv\modrqflt.dll" />
|
||||
<add name="CustomErrorModule" image="%windir%\System32\inetsrv\custerr.dll" />
|
||||
<!--<add name="WebSocketModule" image="%windir%\System32\inetsrv\iiswsock.dll" />-->
|
||||
</globalModules>
|
||||
|
||||
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
|
||||
<scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
|
||||
<staticTypes>
|
||||
<add mimeType="text/*" enabled="true" />
|
||||
<add mimeType="message/*" enabled="true" />
|
||||
<add mimeType="application/javascript" enabled="true" />
|
||||
<add mimeType="application/atom+xml" enabled="true" />
|
||||
<add mimeType="application/xaml+xml" enabled="true" />
|
||||
<add mimeType="image/svg+xml" enabled="true" />
|
||||
<add mimeType="*/*" enabled="false" />
|
||||
</staticTypes>
|
||||
</httpCompression>
|
||||
|
||||
<httpErrors lockAttributes="allowAbsolutePathsWhenDelegated,defaultPath">
|
||||
<error statusCode="401" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="401.htm" />
|
||||
<error statusCode="403" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="403.htm" />
|
||||
<error statusCode="404" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="404.htm" />
|
||||
<error statusCode="405" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="405.htm" />
|
||||
<error statusCode="406" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="406.htm" />
|
||||
<error statusCode="412" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="412.htm" />
|
||||
<error statusCode="500" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="500.htm" />
|
||||
<error statusCode="501" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="501.htm" />
|
||||
<error statusCode="502" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="502.htm" />
|
||||
</httpErrors>
|
||||
|
||||
<httpLogging dontLog="false" />
|
||||
|
||||
<httpProtocol>
|
||||
<customHeaders>
|
||||
<clear />
|
||||
</customHeaders>
|
||||
<redirectHeaders>
|
||||
<clear />
|
||||
</redirectHeaders>
|
||||
</httpProtocol>
|
||||
|
||||
<httpRedirect />
|
||||
|
||||
<httpTracing />
|
||||
|
||||
<isapiFilters />
|
||||
|
||||
<modules>
|
||||
<add name="HttpLoggingModule" lockItem="true" />
|
||||
<add name="HttpCacheModule" lockItem="true" />
|
||||
<add name="StaticCompressionModule" lockItem="true" />
|
||||
<add name="DefaultDocumentModule" lockItem="true" />
|
||||
<add name="DirectoryListingModule" lockItem="true" />
|
||||
<add name="ProtocolSupportModule" lockItem="true" />
|
||||
<add name="StaticFileModule" lockItem="true" />
|
||||
<add name="AnonymousAuthenticationModule" lockItem="true" />
|
||||
<add name="RequestFilteringModule" lockItem="true" />
|
||||
<add name="CustomErrorModule" lockItem="true" />
|
||||
<!--<add name="WebSocketModule" lockItem="true" />-->
|
||||
</modules>
|
||||
|
||||
<odbcLogging />
|
||||
|
||||
<security>
|
||||
|
||||
<access sslFlags="None" />
|
||||
|
||||
<applicationDependencies />
|
||||
|
||||
<authentication>
|
||||
|
||||
<anonymousAuthentication enabled="true" userName="IUSR" />
|
||||
|
||||
<basicAuthentication />
|
||||
|
||||
<clientCertificateMappingAuthentication />
|
||||
|
||||
<digestAuthentication />
|
||||
|
||||
<iisClientCertificateMappingAuthentication />
|
||||
|
||||
</authentication>
|
||||
|
||||
<authorization />
|
||||
|
||||
<ipSecurity />
|
||||
|
||||
<isapiCgiRestriction />
|
||||
|
||||
<requestFiltering>
|
||||
<fileExtensions allowUnlisted="true" applyToWebDAV="true" />
|
||||
<verbs allowUnlisted="true" applyToWebDAV="true" />
|
||||
<hiddenSegments applyToWebDAV="true">
|
||||
<add segment="web.config" />
|
||||
</hiddenSegments>
|
||||
</requestFiltering>
|
||||
|
||||
</security>
|
||||
|
||||
<serverRuntime />
|
||||
|
||||
<serverSideInclude />
|
||||
|
||||
<staticContent lockAttributes="isDocFooterFileName">
|
||||
<mimeMap fileExtension=".323" mimeType="text/h323" />
|
||||
<mimeMap fileExtension=".3g2" mimeType="video/3gpp2" />
|
||||
<mimeMap fileExtension=".3gp2" mimeType="video/3gpp2" />
|
||||
<mimeMap fileExtension=".3gp" mimeType="video/3gpp" />
|
||||
<mimeMap fileExtension=".3gpp" mimeType="video/3gpp" />
|
||||
<mimeMap fileExtension=".aaf" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".aac" mimeType="audio/aac" />
|
||||
<mimeMap fileExtension=".aca" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".accdb" mimeType="application/msaccess" />
|
||||
<mimeMap fileExtension=".accde" mimeType="application/msaccess" />
|
||||
<mimeMap fileExtension=".accdt" mimeType="application/msaccess" />
|
||||
<mimeMap fileExtension=".acx" mimeType="application/internet-property-stream" />
|
||||
<mimeMap fileExtension=".adt" mimeType="audio/vnd.dlna.adts" />
|
||||
<mimeMap fileExtension=".adts" mimeType="audio/vnd.dlna.adts" />
|
||||
<mimeMap fileExtension=".afm" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".ai" mimeType="application/postscript" />
|
||||
<mimeMap fileExtension=".aif" mimeType="audio/x-aiff" />
|
||||
<mimeMap fileExtension=".aifc" mimeType="audio/aiff" />
|
||||
<mimeMap fileExtension=".aiff" mimeType="audio/aiff" />
|
||||
<mimeMap fileExtension=".appcache" mimeType="text/cache-manifest" />
|
||||
<mimeMap fileExtension=".application" mimeType="application/x-ms-application" />
|
||||
<mimeMap fileExtension=".art" mimeType="image/x-jg" />
|
||||
<mimeMap fileExtension=".asd" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".asf" mimeType="video/x-ms-asf" />
|
||||
<mimeMap fileExtension=".asi" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".asm" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".asr" mimeType="video/x-ms-asf" />
|
||||
<mimeMap fileExtension=".asx" mimeType="video/x-ms-asf" />
|
||||
<mimeMap fileExtension=".atom" mimeType="application/atom+xml" />
|
||||
<mimeMap fileExtension=".au" mimeType="audio/basic" />
|
||||
<mimeMap fileExtension=".avi" mimeType="video/avi" />
|
||||
<mimeMap fileExtension=".axs" mimeType="application/olescript" />
|
||||
<mimeMap fileExtension=".bas" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".bcpio" mimeType="application/x-bcpio" />
|
||||
<mimeMap fileExtension=".bin" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".bmp" mimeType="image/bmp" />
|
||||
<mimeMap fileExtension=".c" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".cab" mimeType="application/vnd.ms-cab-compressed" />
|
||||
<mimeMap fileExtension=".calx" mimeType="application/vnd.ms-office.calx" />
|
||||
<mimeMap fileExtension=".cat" mimeType="application/vnd.ms-pki.seccat" />
|
||||
<mimeMap fileExtension=".cdf" mimeType="application/x-cdf" />
|
||||
<mimeMap fileExtension=".chm" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".class" mimeType="application/x-java-applet" />
|
||||
<mimeMap fileExtension=".clp" mimeType="application/x-msclip" />
|
||||
<mimeMap fileExtension=".cmx" mimeType="image/x-cmx" />
|
||||
<mimeMap fileExtension=".cnf" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".cod" mimeType="image/cis-cod" />
|
||||
<mimeMap fileExtension=".cpio" mimeType="application/x-cpio" />
|
||||
<mimeMap fileExtension=".cpp" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".crd" mimeType="application/x-mscardfile" />
|
||||
<mimeMap fileExtension=".crl" mimeType="application/pkix-crl" />
|
||||
<mimeMap fileExtension=".crt" mimeType="application/x-x509-ca-cert" />
|
||||
<mimeMap fileExtension=".csh" mimeType="application/x-csh" />
|
||||
<mimeMap fileExtension=".css" mimeType="text/css" />
|
||||
<mimeMap fileExtension=".csv" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".cur" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".dcr" mimeType="application/x-director" />
|
||||
<mimeMap fileExtension=".deploy" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".der" mimeType="application/x-x509-ca-cert" />
|
||||
<mimeMap fileExtension=".dib" mimeType="image/bmp" />
|
||||
<mimeMap fileExtension=".dir" mimeType="application/x-director" />
|
||||
<mimeMap fileExtension=".disco" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".dll" mimeType="application/x-msdownload" />
|
||||
<mimeMap fileExtension=".dll.config" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".dlm" mimeType="text/dlm" />
|
||||
<mimeMap fileExtension=".doc" mimeType="application/msword" />
|
||||
<mimeMap fileExtension=".docm" mimeType="application/vnd.ms-word.document.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".docx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
|
||||
<mimeMap fileExtension=".dot" mimeType="application/msword" />
|
||||
<mimeMap fileExtension=".dotm" mimeType="application/vnd.ms-word.template.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".dotx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.template" />
|
||||
<mimeMap fileExtension=".dsp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".dtd" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".dvi" mimeType="application/x-dvi" />
|
||||
<mimeMap fileExtension=".dvr-ms" mimeType="video/x-ms-dvr" />
|
||||
<mimeMap fileExtension=".dwf" mimeType="drawing/x-dwf" />
|
||||
<mimeMap fileExtension=".dwp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".dxr" mimeType="application/x-director" />
|
||||
<mimeMap fileExtension=".eml" mimeType="message/rfc822" />
|
||||
<mimeMap fileExtension=".emz" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
|
||||
<mimeMap fileExtension=".eps" mimeType="application/postscript" />
|
||||
<mimeMap fileExtension=".esd" mimeType="application/vnd.ms-cab-compressed" />
|
||||
<mimeMap fileExtension=".etx" mimeType="text/x-setext" />
|
||||
<mimeMap fileExtension=".evy" mimeType="application/envoy" />
|
||||
<mimeMap fileExtension=".exe" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".exe.config" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".fdf" mimeType="application/vnd.fdf" />
|
||||
<mimeMap fileExtension=".fif" mimeType="application/fractals" />
|
||||
<mimeMap fileExtension=".fla" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".flr" mimeType="x-world/x-vrml" />
|
||||
<mimeMap fileExtension=".flv" mimeType="video/x-flv" />
|
||||
<mimeMap fileExtension=".gif" mimeType="image/gif" />
|
||||
<mimeMap fileExtension=".gtar" mimeType="application/x-gtar" />
|
||||
<mimeMap fileExtension=".gz" mimeType="application/x-gzip" />
|
||||
<mimeMap fileExtension=".h" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".hdf" mimeType="application/x-hdf" />
|
||||
<mimeMap fileExtension=".hdml" mimeType="text/x-hdml" />
|
||||
<mimeMap fileExtension=".hhc" mimeType="application/x-oleobject" />
|
||||
<mimeMap fileExtension=".hhk" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".hhp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".hlp" mimeType="application/winhlp" />
|
||||
<mimeMap fileExtension=".hqx" mimeType="application/mac-binhex40" />
|
||||
<mimeMap fileExtension=".hta" mimeType="application/hta" />
|
||||
<mimeMap fileExtension=".htc" mimeType="text/x-component" />
|
||||
<mimeMap fileExtension=".htm" mimeType="text/html" />
|
||||
<mimeMap fileExtension=".html" mimeType="text/html" />
|
||||
<mimeMap fileExtension=".htt" mimeType="text/webviewhtml" />
|
||||
<mimeMap fileExtension=".hxt" mimeType="text/html" />
|
||||
<mimeMap fileExtension=".ico" mimeType="image/x-icon" />
|
||||
<mimeMap fileExtension=".ics" mimeType="text/calendar" />
|
||||
<mimeMap fileExtension=".ief" mimeType="image/ief" />
|
||||
<mimeMap fileExtension=".iii" mimeType="application/x-iphone" />
|
||||
<mimeMap fileExtension=".inf" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".ins" mimeType="application/x-internet-signup" />
|
||||
<mimeMap fileExtension=".isp" mimeType="application/x-internet-signup" />
|
||||
<mimeMap fileExtension=".IVF" mimeType="video/x-ivf" />
|
||||
<mimeMap fileExtension=".jar" mimeType="application/java-archive" />
|
||||
<mimeMap fileExtension=".java" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".jck" mimeType="application/liquidmotion" />
|
||||
<mimeMap fileExtension=".jcz" mimeType="application/liquidmotion" />
|
||||
<mimeMap fileExtension=".jfif" mimeType="image/pjpeg" />
|
||||
<mimeMap fileExtension=".jpb" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".jpe" mimeType="image/jpeg" />
|
||||
<mimeMap fileExtension=".jpeg" mimeType="image/jpeg" />
|
||||
<mimeMap fileExtension=".jpg" mimeType="image/jpeg" />
|
||||
<mimeMap fileExtension=".js" mimeType="application/javascript" />
|
||||
<mimeMap fileExtension=".json" mimeType="application/json" />
|
||||
<mimeMap fileExtension=".jsonld" mimeType="application/ld+json" />
|
||||
<mimeMap fileExtension=".jsx" mimeType="text/jscript" />
|
||||
<mimeMap fileExtension=".latex" mimeType="application/x-latex" />
|
||||
<mimeMap fileExtension=".less" mimeType="text/css" />
|
||||
<mimeMap fileExtension=".lit" mimeType="application/x-ms-reader" />
|
||||
<mimeMap fileExtension=".lpk" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".lsf" mimeType="video/x-la-asf" />
|
||||
<mimeMap fileExtension=".lsx" mimeType="video/x-la-asf" />
|
||||
<mimeMap fileExtension=".lzh" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".m13" mimeType="application/x-msmediaview" />
|
||||
<mimeMap fileExtension=".m14" mimeType="application/x-msmediaview" />
|
||||
<mimeMap fileExtension=".m1v" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".m2ts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||
<mimeMap fileExtension=".m3u" mimeType="audio/x-mpegurl" />
|
||||
<mimeMap fileExtension=".m4a" mimeType="audio/mp4" />
|
||||
<mimeMap fileExtension=".m4v" mimeType="video/mp4" />
|
||||
<mimeMap fileExtension=".man" mimeType="application/x-troff-man" />
|
||||
<mimeMap fileExtension=".manifest" mimeType="application/x-ms-manifest" />
|
||||
<mimeMap fileExtension=".map" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".mdb" mimeType="application/x-msaccess" />
|
||||
<mimeMap fileExtension=".mdp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".me" mimeType="application/x-troff-me" />
|
||||
<mimeMap fileExtension=".mht" mimeType="message/rfc822" />
|
||||
<mimeMap fileExtension=".mhtml" mimeType="message/rfc822" />
|
||||
<mimeMap fileExtension=".mid" mimeType="audio/mid" />
|
||||
<mimeMap fileExtension=".midi" mimeType="audio/mid" />
|
||||
<mimeMap fileExtension=".mix" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".mmf" mimeType="application/x-smaf" />
|
||||
<mimeMap fileExtension=".mno" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".mny" mimeType="application/x-msmoney" />
|
||||
<mimeMap fileExtension=".mov" mimeType="video/quicktime" />
|
||||
<mimeMap fileExtension=".movie" mimeType="video/x-sgi-movie" />
|
||||
<mimeMap fileExtension=".mp2" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".mp3" mimeType="audio/mpeg" />
|
||||
<mimeMap fileExtension=".mp4" mimeType="video/mp4" />
|
||||
<mimeMap fileExtension=".mp4v" mimeType="video/mp4" />
|
||||
<mimeMap fileExtension=".mpa" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".mpe" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".mpeg" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".mpg" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".mpp" mimeType="application/vnd.ms-project" />
|
||||
<mimeMap fileExtension=".mpv2" mimeType="video/mpeg" />
|
||||
<mimeMap fileExtension=".ms" mimeType="application/x-troff-ms" />
|
||||
<mimeMap fileExtension=".msi" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".mso" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".mvb" mimeType="application/x-msmediaview" />
|
||||
<mimeMap fileExtension=".mvc" mimeType="application/x-miva-compiled" />
|
||||
<mimeMap fileExtension=".nc" mimeType="application/x-netcdf" />
|
||||
<mimeMap fileExtension=".nsc" mimeType="video/x-ms-asf" />
|
||||
<mimeMap fileExtension=".nws" mimeType="message/rfc822" />
|
||||
<mimeMap fileExtension=".ocx" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".oda" mimeType="application/oda" />
|
||||
<mimeMap fileExtension=".odc" mimeType="text/x-ms-odc" />
|
||||
<mimeMap fileExtension=".ods" mimeType="application/oleobject" />
|
||||
<mimeMap fileExtension=".oga" mimeType="audio/ogg" />
|
||||
<mimeMap fileExtension=".ogg" mimeType="video/ogg" />
|
||||
<mimeMap fileExtension=".ogv" mimeType="video/ogg" />
|
||||
<mimeMap fileExtension=".one" mimeType="application/onenote" />
|
||||
<mimeMap fileExtension=".onea" mimeType="application/onenote" />
|
||||
<mimeMap fileExtension=".onetoc" mimeType="application/onenote" />
|
||||
<mimeMap fileExtension=".onetoc2" mimeType="application/onenote" />
|
||||
<mimeMap fileExtension=".onetmp" mimeType="application/onenote" />
|
||||
<mimeMap fileExtension=".onepkg" mimeType="application/onenote" />
|
||||
<mimeMap fileExtension=".osdx" mimeType="application/opensearchdescription+xml" />
|
||||
<mimeMap fileExtension=".otf" mimeType="font/otf" />
|
||||
<mimeMap fileExtension=".p10" mimeType="application/pkcs10" />
|
||||
<mimeMap fileExtension=".p12" mimeType="application/x-pkcs12" />
|
||||
<mimeMap fileExtension=".p7b" mimeType="application/x-pkcs7-certificates" />
|
||||
<mimeMap fileExtension=".p7c" mimeType="application/pkcs7-mime" />
|
||||
<mimeMap fileExtension=".p7m" mimeType="application/pkcs7-mime" />
|
||||
<mimeMap fileExtension=".p7r" mimeType="application/x-pkcs7-certreqresp" />
|
||||
<mimeMap fileExtension=".p7s" mimeType="application/pkcs7-signature" />
|
||||
<mimeMap fileExtension=".pbm" mimeType="image/x-portable-bitmap" />
|
||||
<mimeMap fileExtension=".pcx" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".pcz" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".pdf" mimeType="application/pdf" />
|
||||
<mimeMap fileExtension=".pfb" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".pfm" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".pfx" mimeType="application/x-pkcs12" />
|
||||
<mimeMap fileExtension=".pgm" mimeType="image/x-portable-graymap" />
|
||||
<mimeMap fileExtension=".pko" mimeType="application/vnd.ms-pki.pko" />
|
||||
<mimeMap fileExtension=".pma" mimeType="application/x-perfmon" />
|
||||
<mimeMap fileExtension=".pmc" mimeType="application/x-perfmon" />
|
||||
<mimeMap fileExtension=".pml" mimeType="application/x-perfmon" />
|
||||
<mimeMap fileExtension=".pmr" mimeType="application/x-perfmon" />
|
||||
<mimeMap fileExtension=".pmw" mimeType="application/x-perfmon" />
|
||||
<mimeMap fileExtension=".png" mimeType="image/png" />
|
||||
<mimeMap fileExtension=".pnm" mimeType="image/x-portable-anymap" />
|
||||
<mimeMap fileExtension=".pnz" mimeType="image/png" />
|
||||
<mimeMap fileExtension=".pot" mimeType="application/vnd.ms-powerpoint" />
|
||||
<mimeMap fileExtension=".potm" mimeType="application/vnd.ms-powerpoint.template.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".potx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.template" />
|
||||
<mimeMap fileExtension=".ppam" mimeType="application/vnd.ms-powerpoint.addin.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".ppm" mimeType="image/x-portable-pixmap" />
|
||||
<mimeMap fileExtension=".pps" mimeType="application/vnd.ms-powerpoint" />
|
||||
<mimeMap fileExtension=".ppsm" mimeType="application/vnd.ms-powerpoint.slideshow.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".ppsx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slideshow" />
|
||||
<mimeMap fileExtension=".ppt" mimeType="application/vnd.ms-powerpoint" />
|
||||
<mimeMap fileExtension=".pptm" mimeType="application/vnd.ms-powerpoint.presentation.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".pptx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
|
||||
<mimeMap fileExtension=".prf" mimeType="application/pics-rules" />
|
||||
<mimeMap fileExtension=".prm" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".prx" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".ps" mimeType="application/postscript" />
|
||||
<mimeMap fileExtension=".psd" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".psm" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".psp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".pub" mimeType="application/x-mspublisher" />
|
||||
<mimeMap fileExtension=".qt" mimeType="video/quicktime" />
|
||||
<mimeMap fileExtension=".qtl" mimeType="application/x-quicktimeplayer" />
|
||||
<mimeMap fileExtension=".qxd" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".ra" mimeType="audio/x-pn-realaudio" />
|
||||
<mimeMap fileExtension=".ram" mimeType="audio/x-pn-realaudio" />
|
||||
<mimeMap fileExtension=".rar" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".ras" mimeType="image/x-cmu-raster" />
|
||||
<mimeMap fileExtension=".rf" mimeType="image/vnd.rn-realflash" />
|
||||
<mimeMap fileExtension=".rgb" mimeType="image/x-rgb" />
|
||||
<mimeMap fileExtension=".rm" mimeType="application/vnd.rn-realmedia" />
|
||||
<mimeMap fileExtension=".rmi" mimeType="audio/mid" />
|
||||
<mimeMap fileExtension=".roff" mimeType="application/x-troff" />
|
||||
<mimeMap fileExtension=".rpm" mimeType="audio/x-pn-realaudio-plugin" />
|
||||
<mimeMap fileExtension=".rtf" mimeType="application/rtf" />
|
||||
<mimeMap fileExtension=".rtx" mimeType="text/richtext" />
|
||||
<mimeMap fileExtension=".scd" mimeType="application/x-msschedule" />
|
||||
<mimeMap fileExtension=".sct" mimeType="text/scriptlet" />
|
||||
<mimeMap fileExtension=".sea" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".setpay" mimeType="application/set-payment-initiation" />
|
||||
<mimeMap fileExtension=".setreg" mimeType="application/set-registration-initiation" />
|
||||
<mimeMap fileExtension=".sgml" mimeType="text/sgml" />
|
||||
<mimeMap fileExtension=".sh" mimeType="application/x-sh" />
|
||||
<mimeMap fileExtension=".shar" mimeType="application/x-shar" />
|
||||
<mimeMap fileExtension=".sit" mimeType="application/x-stuffit" />
|
||||
<mimeMap fileExtension=".sldm" mimeType="application/vnd.ms-powerpoint.slide.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".sldx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slide" />
|
||||
<mimeMap fileExtension=".smd" mimeType="audio/x-smd" />
|
||||
<mimeMap fileExtension=".smi" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".smx" mimeType="audio/x-smd" />
|
||||
<mimeMap fileExtension=".smz" mimeType="audio/x-smd" />
|
||||
<mimeMap fileExtension=".snd" mimeType="audio/basic" />
|
||||
<mimeMap fileExtension=".snp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".spc" mimeType="application/x-pkcs7-certificates" />
|
||||
<mimeMap fileExtension=".spl" mimeType="application/futuresplash" />
|
||||
<mimeMap fileExtension=".spx" mimeType="audio/ogg" />
|
||||
<mimeMap fileExtension=".src" mimeType="application/x-wais-source" />
|
||||
<mimeMap fileExtension=".ssm" mimeType="application/streamingmedia" />
|
||||
<mimeMap fileExtension=".sst" mimeType="application/vnd.ms-pki.certstore" />
|
||||
<mimeMap fileExtension=".stl" mimeType="application/vnd.ms-pki.stl" />
|
||||
<mimeMap fileExtension=".sv4cpio" mimeType="application/x-sv4cpio" />
|
||||
<mimeMap fileExtension=".sv4crc" mimeType="application/x-sv4crc" />
|
||||
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
|
||||
<mimeMap fileExtension=".svgz" mimeType="image/svg+xml" />
|
||||
<mimeMap fileExtension=".swf" mimeType="application/x-shockwave-flash" />
|
||||
<mimeMap fileExtension=".t" mimeType="application/x-troff" />
|
||||
<mimeMap fileExtension=".tar" mimeType="application/x-tar" />
|
||||
<mimeMap fileExtension=".tcl" mimeType="application/x-tcl" />
|
||||
<mimeMap fileExtension=".tex" mimeType="application/x-tex" />
|
||||
<mimeMap fileExtension=".texi" mimeType="application/x-texinfo" />
|
||||
<mimeMap fileExtension=".texinfo" mimeType="application/x-texinfo" />
|
||||
<mimeMap fileExtension=".tgz" mimeType="application/x-compressed" />
|
||||
<mimeMap fileExtension=".thmx" mimeType="application/vnd.ms-officetheme" />
|
||||
<mimeMap fileExtension=".thn" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".tif" mimeType="image/tiff" />
|
||||
<mimeMap fileExtension=".tiff" mimeType="image/tiff" />
|
||||
<mimeMap fileExtension=".toc" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".tr" mimeType="application/x-troff" />
|
||||
<mimeMap fileExtension=".trm" mimeType="application/x-msterminal" />
|
||||
<mimeMap fileExtension=".ts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||
<mimeMap fileExtension=".tsv" mimeType="text/tab-separated-values" />
|
||||
<mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".tts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||
<mimeMap fileExtension=".txt" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".u32" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".uls" mimeType="text/iuls" />
|
||||
<mimeMap fileExtension=".ustar" mimeType="application/x-ustar" />
|
||||
<mimeMap fileExtension=".vbs" mimeType="text/vbscript" />
|
||||
<mimeMap fileExtension=".vcf" mimeType="text/x-vcard" />
|
||||
<mimeMap fileExtension=".vcs" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".vdx" mimeType="application/vnd.ms-visio.viewer" />
|
||||
<mimeMap fileExtension=".vml" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".vsd" mimeType="application/vnd.visio" />
|
||||
<mimeMap fileExtension=".vss" mimeType="application/vnd.visio" />
|
||||
<mimeMap fileExtension=".vst" mimeType="application/vnd.visio" />
|
||||
<mimeMap fileExtension=".vsto" mimeType="application/x-ms-vsto" />
|
||||
<mimeMap fileExtension=".vsw" mimeType="application/vnd.visio" />
|
||||
<mimeMap fileExtension=".vsx" mimeType="application/vnd.visio" />
|
||||
<mimeMap fileExtension=".vtx" mimeType="application/vnd.visio" />
|
||||
<mimeMap fileExtension=".wav" mimeType="audio/wav" />
|
||||
<mimeMap fileExtension=".wax" mimeType="audio/x-ms-wax" />
|
||||
<mimeMap fileExtension=".wbmp" mimeType="image/vnd.wap.wbmp" />
|
||||
<mimeMap fileExtension=".wcm" mimeType="application/vnd.ms-works" />
|
||||
<mimeMap fileExtension=".wdb" mimeType="application/vnd.ms-works" />
|
||||
<mimeMap fileExtension=".webm" mimeType="video/webm" />
|
||||
<mimeMap fileExtension=".wks" mimeType="application/vnd.ms-works" />
|
||||
<mimeMap fileExtension=".wm" mimeType="video/x-ms-wm" />
|
||||
<mimeMap fileExtension=".wma" mimeType="audio/x-ms-wma" />
|
||||
<mimeMap fileExtension=".wmd" mimeType="application/x-ms-wmd" />
|
||||
<mimeMap fileExtension=".wmf" mimeType="application/x-msmetafile" />
|
||||
<mimeMap fileExtension=".wml" mimeType="text/vnd.wap.wml" />
|
||||
<mimeMap fileExtension=".wmlc" mimeType="application/vnd.wap.wmlc" />
|
||||
<mimeMap fileExtension=".wmls" mimeType="text/vnd.wap.wmlscript" />
|
||||
<mimeMap fileExtension=".wmlsc" mimeType="application/vnd.wap.wmlscriptc" />
|
||||
<mimeMap fileExtension=".wmp" mimeType="video/x-ms-wmp" />
|
||||
<mimeMap fileExtension=".wmv" mimeType="video/x-ms-wmv" />
|
||||
<mimeMap fileExtension=".wmx" mimeType="video/x-ms-wmx" />
|
||||
<mimeMap fileExtension=".wmz" mimeType="application/x-ms-wmz" />
|
||||
<mimeMap fileExtension=".woff" mimeType="font/x-woff" />
|
||||
<mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
|
||||
<mimeMap fileExtension=".wps" mimeType="application/vnd.ms-works" />
|
||||
<mimeMap fileExtension=".wri" mimeType="application/x-mswrite" />
|
||||
<mimeMap fileExtension=".wrl" mimeType="x-world/x-vrml" />
|
||||
<mimeMap fileExtension=".wrz" mimeType="x-world/x-vrml" />
|
||||
<mimeMap fileExtension=".wsdl" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".wtv" mimeType="video/x-ms-wtv" />
|
||||
<mimeMap fileExtension=".wvx" mimeType="video/x-ms-wvx" />
|
||||
<mimeMap fileExtension=".x" mimeType="application/directx" />
|
||||
<mimeMap fileExtension=".xaf" mimeType="x-world/x-vrml" />
|
||||
<mimeMap fileExtension=".xaml" mimeType="application/xaml+xml" />
|
||||
<mimeMap fileExtension=".xap" mimeType="application/x-silverlight-app" />
|
||||
<mimeMap fileExtension=".xbap" mimeType="application/x-ms-xbap" />
|
||||
<mimeMap fileExtension=".xbm" mimeType="image/x-xbitmap" />
|
||||
<mimeMap fileExtension=".xdr" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".xht" mimeType="application/xhtml+xml" />
|
||||
<mimeMap fileExtension=".xhtml" mimeType="application/xhtml+xml" />
|
||||
<mimeMap fileExtension=".xla" mimeType="application/vnd.ms-excel" />
|
||||
<mimeMap fileExtension=".xlam" mimeType="application/vnd.ms-excel.addin.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".xlc" mimeType="application/vnd.ms-excel" />
|
||||
<mimeMap fileExtension=".xlm" mimeType="application/vnd.ms-excel" />
|
||||
<mimeMap fileExtension=".xls" mimeType="application/vnd.ms-excel" />
|
||||
<mimeMap fileExtension=".xlsb" mimeType="application/vnd.ms-excel.sheet.binary.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".xlsm" mimeType="application/vnd.ms-excel.sheet.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".xlsx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
|
||||
<mimeMap fileExtension=".xlt" mimeType="application/vnd.ms-excel" />
|
||||
<mimeMap fileExtension=".xltm" mimeType="application/vnd.ms-excel.template.macroEnabled.12" />
|
||||
<mimeMap fileExtension=".xltx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.template" />
|
||||
<mimeMap fileExtension=".xlw" mimeType="application/vnd.ms-excel" />
|
||||
<mimeMap fileExtension=".xml" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".xof" mimeType="x-world/x-vrml" />
|
||||
<mimeMap fileExtension=".xpm" mimeType="image/x-xpixmap" />
|
||||
<mimeMap fileExtension=".xps" mimeType="application/vnd.ms-xpsdocument" />
|
||||
<mimeMap fileExtension=".xsd" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".xsf" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".xsl" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".xslt" mimeType="text/xml" />
|
||||
<mimeMap fileExtension=".xsn" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".xtp" mimeType="application/octet-stream" />
|
||||
<mimeMap fileExtension=".xwd" mimeType="image/x-xwindowdump" />
|
||||
<mimeMap fileExtension=".z" mimeType="application/x-compress" />
|
||||
<mimeMap fileExtension=".zip" mimeType="application/x-zip-compressed" />
|
||||
</staticContent>
|
||||
|
||||
<tracing>
|
||||
|
||||
<traceFailedRequests />
|
||||
|
||||
<traceProviderDefinitions>
|
||||
<add name="WWW Server" guid="{3a2a4e84-4c21-4981-ae10-3fda0d9b0f83}">
|
||||
<areas>
|
||||
<add name="ANCM" value="65536" />
|
||||
</areas>
|
||||
</add>
|
||||
</traceProviderDefinitions>
|
||||
|
||||
</tracing>
|
||||
|
||||
<urlCompression />
|
||||
|
||||
<validation />
|
||||
<!--<webSocket />-->
|
||||
|
||||
</system.webServer>
|
||||
<location path="" overrideMode="Allow">
|
||||
<system.webServer>
|
||||
|
||||
<handlers accessPolicy="Read, Script">
|
||||
<add name="TRACEVerbHandler" path="*" verb="TRACE" modules="ProtocolSupportModule" requireAccess="None" />
|
||||
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" />
|
||||
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</location>
|
||||
|
||||
</configuration>
|
|
@ -1,287 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class AppOfflineTests : IISFunctionalTestBase
|
||||
{
|
||||
private static readonly TimeSpan RetryDelay = TimeSpan.FromMilliseconds(100);
|
||||
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public AppOfflineTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(HostingModel.InProcess)]
|
||||
[InlineData(HostingModel.OutOfProcess)]
|
||||
public async Task AppOfflineDroppedWhileSiteIsDown_SiteReturns503(HostingModel hostingModel)
|
||||
{
|
||||
var deploymentResult = await DeployApp(hostingModel);
|
||||
|
||||
AddAppOffline(deploymentResult.ContentRoot);
|
||||
|
||||
await AssertAppOffline(deploymentResult);
|
||||
DeletePublishOutput(deploymentResult);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(HostingModel.InProcess)]
|
||||
[InlineData(HostingModel.OutOfProcess)]
|
||||
public async Task LockedAppOfflineDroppedWhileSiteIsDown_SiteReturns503(HostingModel hostingModel)
|
||||
{
|
||||
var deploymentResult = await DeployApp(hostingModel);
|
||||
|
||||
// Add app_offline without shared access
|
||||
using (var stream = File.Open(Path.Combine(deploymentResult.ContentRoot, "app_offline.htm"), FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
|
||||
using (var writer = new StreamWriter(stream))
|
||||
{
|
||||
await writer.WriteLineAsync("App if offline but you wouldn't see this message");
|
||||
await writer.FlushAsync();
|
||||
await AssertAppOffline(deploymentResult, "");
|
||||
}
|
||||
|
||||
DeletePublishOutput(deploymentResult);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(HostingModel.InProcess, 500, "500.0")]
|
||||
[InlineData(HostingModel.OutOfProcess, 502, "502.5")]
|
||||
public async Task AppOfflineDroppedWhileSiteFailedToStartInShim_AppOfflineServed(HostingModel hostingModel, int statusCode, string content)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(hostingModel: hostingModel, publish: true);
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", "nonexistent"));
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var result = await deploymentResult.HttpClient.GetAsync("/");
|
||||
Assert.Equal(statusCode, (int)result.StatusCode);
|
||||
Assert.Contains(content, await result.Content.ReadAsStringAsync());
|
||||
|
||||
AddAppOffline(deploymentResult.ContentRoot);
|
||||
|
||||
await AssertAppOffline(deploymentResult);
|
||||
DeletePublishOutput(deploymentResult);
|
||||
}
|
||||
|
||||
[ConditionalFact(Skip = "https://github.com/aspnet/IISIntegration/issues/933")]
|
||||
public async Task AppOfflineDroppedWhileSiteFailedToStartInRequestHandler_SiteStops_InProcess()
|
||||
{
|
||||
var deploymentResult = await DeployApp(HostingModel.InProcess);
|
||||
|
||||
// Set file content to empty so it fails at runtime
|
||||
File.WriteAllText(Path.Combine(deploymentResult.ContentRoot, "Microsoft.AspNetCore.Server.IIS.dll"), "");
|
||||
|
||||
var result = await deploymentResult.HttpClient.GetAsync("/");
|
||||
Assert.Equal(500, (int)result.StatusCode);
|
||||
Assert.Contains("500.30", await result.Content.ReadAsStringAsync());
|
||||
|
||||
AddAppOffline(deploymentResult.ContentRoot);
|
||||
|
||||
await deploymentResult.AssertRecycledAsync(() => AssertAppOffline(deploymentResult));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.ShutdownToken)]
|
||||
public async Task AppOfflineDroppedWhileSiteStarting_SiteShutsDown_InProcess()
|
||||
{
|
||||
// This test often hits a race between debug logging and stdout redirection closing the handle
|
||||
// we are fine having this race
|
||||
using (AppVerifier.Disable(DeployerSelector.ServerType, 0x300))
|
||||
{
|
||||
var deploymentResult = await DeployApp(HostingModel.InProcess);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
// send first request and add app_offline while app is starting
|
||||
var runningTask = AssertAppOffline(deploymentResult);
|
||||
|
||||
// This test tries to hit a race where we drop app_offline file while
|
||||
// in process application is starting, application start takes at least 400ms
|
||||
// so we back off for 100ms to allow request to reach request handler
|
||||
// Test itself is racy and can result in two scenarios
|
||||
// 1. ANCM detects app_offline before it starts the request - if AssertAppOffline succeeds we've hit it
|
||||
// 2. Intended scenario where app starts and then shuts down
|
||||
// In first case we remove app_offline and try again
|
||||
await Task.Delay(RetryDelay);
|
||||
|
||||
AddAppOffline(deploymentResult.ContentRoot);
|
||||
|
||||
try
|
||||
{
|
||||
await runningTask.DefaultTimeout();
|
||||
|
||||
// if AssertAppOffline succeeded ANCM have picked up app_offline before starting the app
|
||||
// try again
|
||||
RemoveAppOffline(deploymentResult.ContentRoot);
|
||||
}
|
||||
catch
|
||||
{
|
||||
deploymentResult.AssertWorkerProcessStop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True(false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task AppOfflineDroppedWhileSiteRunning_SiteShutsDown_InProcess()
|
||||
{
|
||||
var deploymentResult = await AssertStarts(HostingModel.InProcess);
|
||||
|
||||
AddAppOffline(deploymentResult.ContentRoot);
|
||||
|
||||
await deploymentResult.AssertRecycledAsync(() => AssertAppOffline(deploymentResult));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task AppOfflineDroppedWhileSiteRunning_SiteShutsDown_OutOfProcess()
|
||||
{
|
||||
var deploymentResult = await AssertStarts(HostingModel.OutOfProcess);
|
||||
|
||||
// Repeat dropping file and restarting multiple times
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
AddAppOffline(deploymentResult.ContentRoot);
|
||||
await AssertAppOffline(deploymentResult);
|
||||
RemoveAppOffline(deploymentResult.ContentRoot);
|
||||
await AssertRunning(deploymentResult);
|
||||
}
|
||||
|
||||
AddAppOffline(deploymentResult.ContentRoot);
|
||||
await AssertAppOffline(deploymentResult);
|
||||
DeletePublishOutput(deploymentResult);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(HostingModel.InProcess)]
|
||||
[InlineData(HostingModel.OutOfProcess)]
|
||||
public async Task AppOfflineDropped_CanRemoveAppOfflineAfterAddingAndSiteWorks(HostingModel hostingModel)
|
||||
{
|
||||
var deploymentResult = await DeployApp(hostingModel);
|
||||
|
||||
AddAppOffline(deploymentResult.ContentRoot);
|
||||
|
||||
await AssertAppOffline(deploymentResult);
|
||||
|
||||
RemoveAppOffline(deploymentResult.ContentRoot);
|
||||
|
||||
await AssertRunning(deploymentResult);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(HostingModel.InProcess)]
|
||||
[InlineData(HostingModel.OutOfProcess)]
|
||||
public async Task AppOfflineAddedAndRemovedStress(HostingModel hostingModel)
|
||||
{
|
||||
var deploymentResult = await AssertStarts(hostingModel);
|
||||
|
||||
var load = Helpers.StressLoad(deploymentResult.HttpClient, "/HelloWorld", response => {
|
||||
var statusCode = (int)response.StatusCode;
|
||||
Assert.True(statusCode == 200 || statusCode == 503, "Status code was " + statusCode);
|
||||
});
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
// AddAppOffline might fail if app_offline is being read by ANCM and deleted at the same time
|
||||
RetryHelper.RetryOperation(
|
||||
() => AddAppOffline(deploymentResult.ContentRoot),
|
||||
e => Logger.LogError($"Failed to create app_offline : {e.Message}"),
|
||||
retryCount: 3,
|
||||
retryDelayMilliseconds: RetryDelay.Milliseconds);
|
||||
RemoveAppOffline(deploymentResult.ContentRoot);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await load;
|
||||
}
|
||||
catch (HttpRequestException ex) when (ex.InnerException is IOException | ex.InnerException is SocketException)
|
||||
{
|
||||
// IOException in InProcess is fine, just means process stopped
|
||||
if (hostingModel != HostingModel.InProcess)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<IISDeploymentResult> DeployApp(HostingModel hostingModel = HostingModel.InProcess)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(hostingModel: hostingModel, publish: true);
|
||||
|
||||
return await DeployAsync(deploymentParameters);
|
||||
}
|
||||
|
||||
private void AddAppOffline(string appPath, string content = "The app is offline.")
|
||||
{
|
||||
File.WriteAllText(Path.Combine(appPath, "app_offline.htm"), content);
|
||||
}
|
||||
|
||||
private void RemoveAppOffline(string appPath)
|
||||
{
|
||||
RetryHelper.RetryOperation(
|
||||
() => File.Delete(Path.Combine(appPath, "app_offline.htm")),
|
||||
e => Logger.LogError($"Failed to remove app_offline : {e.Message}"),
|
||||
retryCount: 3,
|
||||
retryDelayMilliseconds: RetryDelay.Milliseconds);
|
||||
}
|
||||
|
||||
private async Task AssertAppOffline(IISDeploymentResult deploymentResult, string expectedResponse = "The app is offline.")
|
||||
{
|
||||
var response = await deploymentResult.HttpClient.RetryRequestAsync("HelloWorld", r => r.StatusCode == HttpStatusCode.ServiceUnavailable);
|
||||
Assert.Equal(expectedResponse, await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
private async Task<IISDeploymentResult> AssertStarts(HostingModel hostingModel)
|
||||
{
|
||||
var deploymentResult = await DeployApp(hostingModel);
|
||||
|
||||
await AssertRunning(deploymentResult);
|
||||
|
||||
return deploymentResult;
|
||||
}
|
||||
|
||||
private static async Task AssertRunning(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
var response = await deploymentResult.HttpClient.RetryRequestAsync("HelloWorld", r => r.IsSuccessStatusCode);
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("Hello World", responseText);
|
||||
}
|
||||
|
||||
private void DeletePublishOutput(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
foreach (var file in Directory.GetFiles(deploymentResult.ContentRoot, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
// Out of process module dll is allowed to be locked
|
||||
var name = Path.GetFileName(file);
|
||||
if (name == "aspnetcore.dll" || name == "aspnetcorev2.dll" || name == "aspnetcorev2_outofprocess.dll")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
File.Delete(file);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class BasicAuthTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public BasicAuthTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
public static TestMatrix TestVariants
|
||||
=> TestMatrix.ForServers(DeployerSelector.ServerType)
|
||||
.WithTfms(Tfm.NetCoreApp22)
|
||||
.WithApplicationTypes(ApplicationType.Portable)
|
||||
.WithAllAncmVersions()
|
||||
.WithAllHostingModels();
|
||||
|
||||
[ConditionalTheory]
|
||||
[RequiresEnvironmentVariable("ASPNETCORE_MODULE_TEST_USER")]
|
||||
[RequiresIIS(IISCapability.BasicAuthentication)]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task BasicAuthTest(TestVariant variant)
|
||||
{
|
||||
var username = Environment.GetEnvironmentVariable("ASPNETCORE_MODULE_TEST_USER");
|
||||
var password = Environment.GetEnvironmentVariable("ASPNETCORE_MODULE_TEST_PASSWORD");
|
||||
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
deploymentParameters.SetAnonymousAuth(enabled: false);
|
||||
deploymentParameters.SetWindowsAuth(enabled: false);
|
||||
deploymentParameters.SetBasicAuth(enabled: true);
|
||||
|
||||
// The default in hosting sets windows auth to true.
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, "/Auth");
|
||||
var byteArray = new UTF8Encoding().GetBytes(username + ":" + password);
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
|
||||
|
||||
var response = await deploymentResult.HttpClient.SendAsync(request);
|
||||
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
if (variant.HostingModel == HostingModel.InProcess)
|
||||
{
|
||||
Assert.StartsWith("Windows", responseText);
|
||||
Assert.Contains(username, responseText);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We expect out-of-proc not allowing basic auth
|
||||
Assert.Equal("Windows", responseText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public class ClientCertificateFixture : IDisposable
|
||||
{
|
||||
private X509Certificate2 _certificate;
|
||||
private const string _certIssuerPrefix = "CN=IISIntegrationTest_Root";
|
||||
|
||||
public X509Certificate2 GetOrCreateCertificate()
|
||||
{
|
||||
if (_certificate != null)
|
||||
{
|
||||
return _certificate;
|
||||
}
|
||||
|
||||
using (var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine))
|
||||
{
|
||||
store.Open(OpenFlags.ReadWrite);
|
||||
var parentKey = CreateKeyMaterial(2048);
|
||||
|
||||
// Create a cert name with a random guid to avoid name conflicts
|
||||
var parentRequest = new CertificateRequest(
|
||||
_certIssuerPrefix + Guid.NewGuid().ToString(),
|
||||
parentKey, HashAlgorithmName.SHA256,
|
||||
RSASignaturePadding.Pkcs1);
|
||||
|
||||
parentRequest.CertificateExtensions.Add(
|
||||
new X509BasicConstraintsExtension(
|
||||
certificateAuthority: true,
|
||||
hasPathLengthConstraint: false,
|
||||
pathLengthConstraint: 0,
|
||||
critical: true));
|
||||
|
||||
parentRequest.CertificateExtensions.Add(
|
||||
new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation, critical: true));
|
||||
|
||||
parentRequest.CertificateExtensions.Add(
|
||||
new X509SubjectKeyIdentifierExtension(parentRequest.PublicKey, false));
|
||||
|
||||
var notBefore = DateTimeOffset.Now.AddDays(-1);
|
||||
var notAfter = DateTimeOffset.Now.AddYears(5);
|
||||
|
||||
var parentCert = parentRequest.CreateSelfSigned(notBefore, notAfter);
|
||||
|
||||
// Need to export/import the certificate to associate the private key with the cert.
|
||||
var imported = parentCert;
|
||||
|
||||
var export = parentCert.Export(X509ContentType.Pkcs12, "");
|
||||
imported = new X509Certificate2(export, "", X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
|
||||
Array.Clear(export, 0, export.Length);
|
||||
|
||||
// Add the cert to the cert store
|
||||
_certificate = imported;
|
||||
|
||||
store.Add(certificate: imported);
|
||||
store.Close();
|
||||
return imported;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_certificate == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine))
|
||||
{
|
||||
store.Open(OpenFlags.ReadWrite);
|
||||
store.Remove(_certificate);
|
||||
|
||||
// Remove any extra certs that were left by previous tests.
|
||||
for (var i = store.Certificates.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var cert = store.Certificates[i];
|
||||
if (cert.Issuer.StartsWith(_certIssuerPrefix))
|
||||
{
|
||||
store.Remove(cert);
|
||||
}
|
||||
}
|
||||
store.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private RSA CreateKeyMaterial(int minimumKeySize)
|
||||
{
|
||||
var rsa = RSA.Create(minimumKeySize);
|
||||
if (rsa.KeySize < minimumKeySize)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to create a key with a size of {minimumKeySize} bits");
|
||||
}
|
||||
|
||||
return rsa;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.Common;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
[SkipIfNotAdmin]
|
||||
public class ClientCertificateTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
private readonly ClientCertificateFixture _certFixture;
|
||||
|
||||
public ClientCertificateTests(PublishedSitesFixture fixture, ClientCertificateFixture certFixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
_certFixture = certFixture;
|
||||
}
|
||||
|
||||
public static TestMatrix TestVariants
|
||||
=> TestMatrix.ForServers(DeployerSelector.ServerType)
|
||||
.WithTfms(Tfm.NetCoreApp22, Tfm.Net461)
|
||||
.WithAllApplicationTypes()
|
||||
.WithAllAncmVersions()
|
||||
.WithAllHostingModels();
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public Task HttpsNoClientCert_NoClientCert(TestVariant variant)
|
||||
{
|
||||
return ClientCertTest(variant, sendClientCert: false);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public Task HttpsClientCert_GetCertInformation(TestVariant variant)
|
||||
{
|
||||
return ClientCertTest(variant, sendClientCert: true);
|
||||
}
|
||||
|
||||
private async Task ClientCertTest(TestVariant variant, bool sendClientCert)
|
||||
{
|
||||
var port = TestPortHelper.GetNextSSLPort();
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant);
|
||||
deploymentParameters.ApplicationBaseUriHint = $"https://localhost:{port}/";
|
||||
deploymentParameters.AddHttpsToServerConfig();
|
||||
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
ServerCertificateCustomValidationCallback = (a, b, c, d) => true,
|
||||
ClientCertificateOptions = ClientCertificateOption.Manual,
|
||||
};
|
||||
|
||||
X509Certificate2 cert = null;
|
||||
if (sendClientCert)
|
||||
{
|
||||
cert = _certFixture.GetOrCreateCertificate();
|
||||
handler.ClientCertificates.Add(cert);
|
||||
}
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var client = deploymentResult.CreateClient(handler);
|
||||
var response = await client.GetAsync("GetClientCert");
|
||||
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
try
|
||||
{
|
||||
if (sendClientCert)
|
||||
{
|
||||
Assert.Equal($"Enabled;{cert.GetCertHashString()}", responseText);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal("Disabled", responseText);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"Certificate is invalid. Issuer name: {cert.Issuer}");
|
||||
using (var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine))
|
||||
{
|
||||
Logger.LogError($"List of current certificates in root store:");
|
||||
store.Open(OpenFlags.ReadWrite);
|
||||
foreach (var otherCert in store.Certificates)
|
||||
{
|
||||
Logger.LogError(otherCert.Issuer);
|
||||
}
|
||||
store.Close();
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class ClientDisconnectStressTests: FunctionalTestsBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public ClientDisconnectStressTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(HostingModel.InProcess)]
|
||||
[InlineData(HostingModel.OutOfProcess)]
|
||||
public async Task ClientDisconnectStress(HostingModel hostingModel)
|
||||
{
|
||||
var site = await StartAsync(_fixture.GetBaseDeploymentParameters(hostingModel));
|
||||
var maxRequestSize = 1000;
|
||||
var blockSize = 40;
|
||||
var random = new Random();
|
||||
async Task RunRequests()
|
||||
{
|
||||
using (var connection = new TestConnection(site.HttpClient.BaseAddress.Port))
|
||||
{
|
||||
await connection.Send(
|
||||
"POST /ReadAndFlushEcho HTTP/1.1",
|
||||
$"Content-Length: {maxRequestSize}",
|
||||
"Host: localhost",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
|
||||
var disconnectAfter = random.Next(maxRequestSize);
|
||||
var data = new byte[blockSize];
|
||||
for (int i = 0; i < disconnectAfter / blockSize; i++)
|
||||
{
|
||||
await connection.Stream.WriteAsync(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Task> tasks = new List<Task>();
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
tasks.Add(Task.Run(RunRequests));
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
StopServer();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class CommonStartupTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public CommonStartupTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
public static TestMatrix TestVariants
|
||||
=> TestMatrix.ForServers(DeployerSelector.ServerType)
|
||||
.WithTfms(Tfm.NetCoreApp22)
|
||||
.WithAllApplicationTypes()
|
||||
.WithAllAncmVersions()
|
||||
.WithAllHostingModels();
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task StartupStress(TestVariant variant)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await Helpers.StressLoad(deploymentResult.HttpClient, "/HelloWorld", response => {
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("Hello World", response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISCompressionSiteCollection.Name)]
|
||||
public abstract class CompressionTests : FixtureLoggedTest
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class InProc: CompressionTests
|
||||
{
|
||||
public InProc(IISTestSiteFixture fixture) : base(fixture) { }
|
||||
}
|
||||
|
||||
[Collection(OutOfProcessTestSiteCollection.Name)]
|
||||
public class OutOfProcess: CompressionTests
|
||||
{
|
||||
public OutOfProcess(OutOfProcessTestSiteFixture fixture) : base(fixture) { }
|
||||
}
|
||||
|
||||
[Collection(OutOfProcessV1TestSiteCollection.Name)]
|
||||
public class OutOfProcessV1: CompressionTests
|
||||
{
|
||||
public OutOfProcessV1(OutOfProcessV1TestSiteFixture fixture) : base(fixture) { }
|
||||
}
|
||||
|
||||
protected CompressionTests(IISTestSiteFixture fixture) : base(fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task PassesThroughCompression()
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, "/CompressedData");
|
||||
|
||||
request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
|
||||
|
||||
var response = await _fixture.Client.SendAsync(request);
|
||||
Assert.Equal("gzip", response.Content.Headers.ContentEncoding.Single());
|
||||
Assert.Equal(
|
||||
new byte[] {
|
||||
0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x0B, 0x63, 0x60, 0xA0, 0x3D, 0x00, 0x00,
|
||||
0xCA, 0xC6, 0x88, 0x99, 0x64, 0x00, 0x00, 0x00 },
|
||||
await response.Content.ReadAsByteArrayAsync());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class ConfigurationChangeTests : IISFunctionalTestBase
|
||||
{
|
||||
private static readonly TimeSpan RetryDelay = TimeSpan.FromMilliseconds(100);
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public ConfigurationChangeTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ConfigurationChangeStopsInProcess()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.InProcess, publish: true);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await deploymentResult.AssertStarts();
|
||||
|
||||
// Just "touching" web.config should be enough
|
||||
deploymentResult.ModifyWebConfig(element => {});
|
||||
|
||||
await deploymentResult.AssertRecycledAsync();
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(AncmVersion.AspNetCoreModule)]
|
||||
[InlineData(AncmVersion.AspNetCoreModuleV2)]
|
||||
public async Task ConfigurationChangeForcesChildProcessRestart(AncmVersion version)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true);
|
||||
deploymentParameters.AncmVersion = version;
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var processBefore = await deploymentResult.HttpClient.GetStringAsync("/ProcessId");
|
||||
|
||||
// Just "touching" web.config should be enough
|
||||
deploymentResult.ModifyWebConfig(element => {});
|
||||
|
||||
// Have to retry here to allow ANCM to receive notification and react to it
|
||||
// Verify that worker process gets restarted with new process id
|
||||
await deploymentResult.HttpClient.RetryRequestAsync("/ProcessId", async r => await r.Content.ReadAsStringAsync() != processBefore);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task OutOfProcessToInProcessHostingModelSwitchWorks()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await deploymentResult.AssertStarts();
|
||||
|
||||
deploymentResult.ModifyWebConfig(element => element
|
||||
.Descendants("system.webServer")
|
||||
.Single()
|
||||
.GetOrAdd("aspNetCore")
|
||||
.SetAttributeValue("hostingModel", "inprocess"));
|
||||
|
||||
// Have to retry here to allow ANCM to receive notification and react to it
|
||||
// Verify that inprocess application was created and tried to start
|
||||
await deploymentResult.HttpClient.RetryRequestAsync("/HelloWorld", r => r.StatusCode == HttpStatusCode.InternalServerError);
|
||||
|
||||
StopServer();
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Could not find the assembly 'aspnetcorev2_inprocess.dll'", Logger);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(HostingModel.InProcess)]
|
||||
[InlineData(HostingModel.OutOfProcess)]
|
||||
public async Task ConfigurationTouchedStress(HostingModel hostingModel)
|
||||
{
|
||||
var deploymentResult = await DeployAsync(_fixture.GetBaseDeploymentParameters(hostingModel, publish: true));
|
||||
|
||||
await deploymentResult.AssertStarts();
|
||||
var load = Helpers.StressLoad(deploymentResult.HttpClient, "/HelloWorld", response => {
|
||||
var statusCode = (int)response.StatusCode;
|
||||
Assert.True(statusCode == 200 || statusCode == 503, "Status code was " + statusCode);
|
||||
});
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
// ModifyWebConfig might fail if web.config is being read by IIS
|
||||
RetryHelper.RetryOperation(
|
||||
() => deploymentResult.ModifyWebConfig(element => {}),
|
||||
e => Logger.LogError($"Failed to touch web.config : {e.Message}"),
|
||||
retryCount: 3,
|
||||
retryDelayMilliseconds: RetryDelay.Milliseconds);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await load;
|
||||
}
|
||||
catch (HttpRequestException ex) when (ex.InnerException is IOException | ex.InnerException is SocketException)
|
||||
{
|
||||
// IOException in InProcess is fine, just means process stopped
|
||||
if (hostingModel != HostingModel.InProcess)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class ClientDisconnectTests: FixtureLoggedTest
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public ClientDisconnectTests(IISTestSiteFixture fixture): base(fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ServerWorksAfterClientDisconnect()
|
||||
{
|
||||
using (var connection = _fixture.CreateTestConnection())
|
||||
{
|
||||
var message = "Hello";
|
||||
await connection.Send(
|
||||
"POST /ReadAndWriteSynchronously HTTP/1.1",
|
||||
$"Content-Length: {100000}",
|
||||
"Host: localhost",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
|
||||
await connection.Send(message);
|
||||
|
||||
await connection.Receive(
|
||||
"HTTP/1.1 200 OK",
|
||||
"");
|
||||
}
|
||||
|
||||
var response = await _fixture.Client.GetAsync("HelloWorld");
|
||||
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("Hello World", responseText);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RequestAbortedTokenFires()
|
||||
{
|
||||
using (var connection = _fixture.CreateTestConnection())
|
||||
{
|
||||
await connection.Send(
|
||||
"GET /WaitForAbort HTTP/1.1",
|
||||
"Host: localhost",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
|
||||
await _fixture.Client.RetryRequestAsync("/WaitingRequestCount", async message => await message.Content.ReadAsStringAsync() == "1");
|
||||
}
|
||||
|
||||
await _fixture.Client.RetryRequestAsync("/WaitingRequestCount", async message => await message.Content.ReadAsStringAsync() == "0");
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ClientDisconnectCallbackStress()
|
||||
{
|
||||
// Fixture initialization fails if inside of the Task.Run, so send an
|
||||
// initial request to initialize the fixture.
|
||||
var response = await _fixture.Client.GetAsync("HelloWorld");
|
||||
var numTotalRequests = 0;
|
||||
for (var j = 0; j < 20; j++)
|
||||
{
|
||||
// Windows has a max connection limit of 10 for the IIS server,
|
||||
// so setting limit fairly low.
|
||||
const int numRequests = 5;
|
||||
async Task RunRequests()
|
||||
{
|
||||
using (var connection = _fixture.CreateTestConnection())
|
||||
{
|
||||
await connection.Send(
|
||||
"GET /WaitForAbort HTTP/1.1",
|
||||
"Host: localhost",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
await _fixture.Client.RetryRequestAsync("/WaitingRequestCount", async message => await message.Content.ReadAsStringAsync() != "0");
|
||||
Interlocked.Increment(ref numTotalRequests);
|
||||
}
|
||||
}
|
||||
|
||||
List<Task> tasks = new List<Task>();
|
||||
for (int i = 0; i < numRequests; i++)
|
||||
{
|
||||
tasks.Add(Task.Run(RunRequests));
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
await _fixture.Client.RetryRequestAsync("/WaitingRequestCount", async message => await message.Content.ReadAsStringAsync() == "0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISCompressionSiteCollection.Name)]
|
||||
public class CompressionModuleTests : FixtureLoggedTest
|
||||
{
|
||||
private readonly IISCompressionSiteFixture _fixture;
|
||||
|
||||
public CompressionModuleTests(IISCompressionSiteFixture fixture): base(fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[RequiresIIS(IISCapability.DynamicCompression)]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public async Task BufferingDisabled(bool compression)
|
||||
{
|
||||
using (var connection = _fixture.CreateTestConnection())
|
||||
{
|
||||
var requestLength = 0;
|
||||
var messages = new List<string>();
|
||||
for (var i = 1; i < 100; i++)
|
||||
{
|
||||
var message = i + Environment.NewLine;
|
||||
requestLength += message.Length;
|
||||
messages.Add(message);
|
||||
}
|
||||
|
||||
await connection.Send(
|
||||
"POST /ReadAndWriteEchoLinesNoBuffering HTTP/1.1",
|
||||
$"Content-Length: {requestLength}",
|
||||
"Accept-Encoding: " + (compression ? "gzip": "identity"),
|
||||
"Response-Content-Type: text/event-stream",
|
||||
"Host: localhost",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
|
||||
await connection.Receive(
|
||||
"HTTP/1.1 200 OK",
|
||||
"");
|
||||
await connection.ReceiveHeaders();
|
||||
|
||||
foreach (var message in messages)
|
||||
{
|
||||
await connection.Send(message);
|
||||
await connection.ReceiveChunk(message);
|
||||
}
|
||||
|
||||
await connection.Send("\r\n");
|
||||
await connection.ReceiveChunk("");
|
||||
await connection.WaitForConnectionClose();
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.DynamicCompression)]
|
||||
public async Task DynamicResponsesAreCompressed()
|
||||
{
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
AutomaticDecompression = DecompressionMethods.GZip
|
||||
};
|
||||
var client = new HttpClient(handler)
|
||||
{
|
||||
BaseAddress = _fixture.Client.BaseAddress,
|
||||
};
|
||||
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
|
||||
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("identity", 0));
|
||||
client.DefaultRequestHeaders.Add("Response-Content-Type", "text/event-stream");
|
||||
var messages = "Message1\r\nMessage2\r\n";
|
||||
|
||||
// Send messages with terminator
|
||||
var response = await client.PostAsync("ReadAndWriteEchoLines", new StringContent(messages + "\r\n"));
|
||||
Assert.Equal(messages, await response.Content.ReadAsStringAsync());
|
||||
Assert.True(response.Content.Headers.TryGetValues("Content-Type", out var contentTypes));
|
||||
Assert.Single(contentTypes, "text/event-stream");
|
||||
// Not the cleanest check but I wasn't able to figure out other way to check
|
||||
// that response was compressed
|
||||
Assert.Contains("gzip", response.Content.GetType().FullName, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class EnvironmentVariableTests: FixtureLoggedTest
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public EnvironmentVariableTests(IISTestSiteFixture fixture): base(fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task GetUniqueEnvironmentVariable()
|
||||
{
|
||||
Assert.Equal("foobar", await _fixture.Client.GetStringAsync("/CheckEnvironmentVariable"));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task GetLongEnvironmentVariable()
|
||||
{
|
||||
Assert.Equal(
|
||||
"AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" +
|
||||
"AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" +
|
||||
"AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" +
|
||||
"AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" +
|
||||
"AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" +
|
||||
"AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative",
|
||||
await _fixture.Client.GetStringAsync("/CheckEnvironmentLongValueVariable"));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task GetExistingEnvironmentVariable()
|
||||
{
|
||||
Assert.Contains(";foobarbaz", await _fixture.Client.GetStringAsync("/CheckAppendedEnvironmentVariable"));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task AuthHeaderEnvironmentVariableRemoved()
|
||||
{
|
||||
Assert.DoesNotContain("shouldberemoved", await _fixture.Client.GetStringAsync("/CheckRemoveAuthEnvironmentVariable"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class ErrorPagesTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public ErrorPagesTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
public async Task IncludesAdditionalErrorPageTextInProcessHandlerLoadFailure_CorrectString()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
var response = await DeployAppWithStartupFailure(deploymentParameters);
|
||||
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
Assert.Contains("HTTP Error 500.0 - ANCM In-Process Handler Load Failure", responseString);
|
||||
VerifyNoExtraTrailingBytes(responseString);
|
||||
|
||||
await AssertLink(response);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
public async Task IncludesAdditionalErrorPageTextOutOfProcessStartupFailure_CorrectString()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true);
|
||||
var response = await DeployAppWithStartupFailure(deploymentParameters);
|
||||
|
||||
Assert.Equal(HttpStatusCode.BadGateway, response.StatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
Assert.Contains("HTTP Error 502.5 - ANCM Out-Of-Process Startup Failure", responseString);
|
||||
VerifyNoExtraTrailingBytes(responseString);
|
||||
|
||||
await AssertLink(response);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
public async Task IncludesAdditionalErrorPageTextOutOfProcessHandlerLoadFailure_CorrectString()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true);
|
||||
deploymentParameters.HandlerSettings["handlerVersion"] = "88.93";
|
||||
deploymentParameters.EnvironmentVariables["ANCM_ADDITIONAL_ERROR_PAGE_LINK"] = "http://example";
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
var response = await deploymentResult.HttpClient.GetAsync("HelloWorld");
|
||||
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
Assert.Contains("HTTP Error 500.0 - ANCM Out-Of-Process Handler Load Failure", responseString);
|
||||
VerifyNoExtraTrailingBytes(responseString);
|
||||
|
||||
await AssertLink(response);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
[RequiresNewHandler]
|
||||
public async Task IncludesAdditionalErrorPageTextInProcessStartupFailure_CorrectString()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} EarlyReturn");
|
||||
deploymentParameters.EnvironmentVariables["ANCM_ADDITIONAL_ERROR_PAGE_LINK"] = "http://example";
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
var response = await deploymentResult.HttpClient.GetAsync("HelloWorld");
|
||||
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
Assert.Contains("HTTP Error 500.30 - ANCM In-Process Start Failure", responseString);
|
||||
VerifyNoExtraTrailingBytes(responseString);
|
||||
|
||||
await AssertLink(response);
|
||||
}
|
||||
|
||||
private static void VerifyNoExtraTrailingBytes(string responseString)
|
||||
{
|
||||
if (!DeployerSelector.IsBackwardsCompatiblityTest)
|
||||
{
|
||||
Assert.EndsWith("</html>\r\n", responseString);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task AssertLink(HttpResponseMessage response)
|
||||
{
|
||||
Assert.Contains("<a href=\"http://example\"> <cite> http://example </cite></a> and ", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> DeployAppWithStartupFailure(IISDeploymentParameters deploymentParameters)
|
||||
{
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", "doesnot"));
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("arguments", "start"));
|
||||
|
||||
deploymentParameters.EnvironmentVariables["ANCM_ADDITIONAL_ERROR_PAGE_LINK"] = "http://example";
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
return await deploymentResult.HttpClient.GetAsync("HelloWorld");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class EventLogTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public EventLogTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task CheckStartupEventLogMessage()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
await deploymentResult.AssertStarts();
|
||||
|
||||
StopServer();
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Application '.+' started the coreclr in-process successfully.");
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task CheckShutdownEventLogMessage()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
await deploymentResult.AssertStarts();
|
||||
|
||||
StopServer();
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Application '.+' has shutdown.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class FeatureCollectionTest
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public FeatureCollectionTest(IISTestSiteFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("FeatureCollectionSetRequestFeatures")]
|
||||
[InlineData("FeatureCollectionSetResponseFeatures")]
|
||||
[InlineData("FeatureCollectionSetConnectionFeatures")]
|
||||
public async Task FeatureCollectionTest_SetHttpContextFeatures(string path)
|
||||
{
|
||||
Assert.Equal("Success", await _fixture.Client.GetStringAsync(path + "/path" + "?query"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public class FixtureLoggedTest: LoggedTest
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public FixtureLoggedTest(IISTestSiteFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
public override void Initialize(MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
base.Initialize(methodInfo, testMethodArguments, testOutputHelper);
|
||||
_fixture.Attach(this);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
_fixture.Detach(this);
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,181 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class FrebTests : LogFileTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
public FrebTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
public static IList<FrebLogItem> FrebChecks()
|
||||
{
|
||||
var list = new List<FrebLogItem>();
|
||||
list.Add(new FrebLogItem("ANCM_INPROC_EXECUTE_REQUEST_START"));
|
||||
list.Add(new FrebLogItem("ANCM_INPROC_EXECUTE_REQUEST_COMPLETION", "1"));
|
||||
list.Add(new FrebLogItem("ANCM_INPROC_ASYNC_COMPLETION_START"));
|
||||
list.Add(new FrebLogItem("ANCM_INPROC_ASYNC_COMPLETION_COMPLETION", "0"));
|
||||
list.Add(new FrebLogItem("ANCM_INPROC_MANAGED_REQUEST_COMPLETION"));
|
||||
return list;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.FailedRequestTracingModule)]
|
||||
public async Task CheckCommonFrebEvents()
|
||||
{
|
||||
var result = await SetupFrebApp();
|
||||
|
||||
await result.HttpClient.GetAsync("HelloWorld");
|
||||
|
||||
StopServer();
|
||||
|
||||
AssertFrebLogs(result, FrebChecks());
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresNewShim]
|
||||
[RequiresIIS(IISCapability.FailedRequestTracingModule)]
|
||||
public async Task FrebIncludesHResultFailures()
|
||||
{
|
||||
var parameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
parameters.TransformArguments((args, _) => string.Empty);
|
||||
var result = await SetupFrebApp(parameters);
|
||||
|
||||
await result.HttpClient.GetAsync("HelloWorld");
|
||||
|
||||
StopServer();
|
||||
|
||||
AssertFrebLogs(result, new FrebLogItem("ANCM_HRESULT_FAILED"), new FrebLogItem("ANCM_EXCEPTION_CAUGHT"));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.FailedRequestTracingModule)]
|
||||
public async Task CheckFailedRequestEvents()
|
||||
{
|
||||
var result = await SetupFrebApp();
|
||||
|
||||
await result.HttpClient.GetAsync("Throw");
|
||||
|
||||
StopServer();
|
||||
|
||||
AssertFrebLogs(result, new FrebLogItem("ANCM_INPROC_ASYNC_COMPLETION_COMPLETION", "2"));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.FailedRequestTracingModule)]
|
||||
public async Task CheckFrebDisconnect()
|
||||
{
|
||||
var result = await SetupFrebApp();
|
||||
|
||||
using (var connection = new TestConnection(result.HttpClient.BaseAddress.Port))
|
||||
{
|
||||
await connection.Send(
|
||||
"GET /WaitForAbort HTTP/1.1",
|
||||
"Host: localhost",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
await result.HttpClient.RetryRequestAsync("/WaitingRequestCount", async message => await message.Content.ReadAsStringAsync() == "1");
|
||||
}
|
||||
|
||||
StopServer();
|
||||
|
||||
// The order of freb logs is based on when the requests are complete.
|
||||
// This is non-deterministic here, so we need to check both freb files for a request that was disconnected.
|
||||
AssertFrebLogs(result, new FrebLogItem("ANCM_INPROC_REQUEST_DISCONNECT"), new FrebLogItem("ANCM_INPROC_MANAGED_REQUEST_COMPLETION"));
|
||||
}
|
||||
|
||||
private async Task<IISDeploymentResult> SetupFrebApp(IISDeploymentParameters parameters = null)
|
||||
{
|
||||
parameters = parameters ?? _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
parameters.EnableFreb("Verbose", _logFolderPath);
|
||||
|
||||
Directory.CreateDirectory(_logFolderPath);
|
||||
var result = await DeployAsync(parameters);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void AssertFrebLogs(IISDeploymentResult result, params FrebLogItem[] expectedFrebEvents)
|
||||
{
|
||||
AssertFrebLogs(result, (IEnumerable<FrebLogItem>)expectedFrebEvents);
|
||||
}
|
||||
|
||||
private void AssertFrebLogs(IISDeploymentResult result, IEnumerable<FrebLogItem> expectedFrebEvents)
|
||||
{
|
||||
var frebEvent = GetFrebLogItems(result);
|
||||
foreach (var expectedEvent in expectedFrebEvents)
|
||||
{
|
||||
Assert.Contains(expectedEvent, frebEvent);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<FrebLogItem> GetFrebLogItems(IISDeploymentResult result)
|
||||
{
|
||||
var folderPath = Helpers.GetFrebFolder(_logFolderPath, result);
|
||||
var xmlFiles = Directory.GetFiles(folderPath).Where(f => f.EndsWith("xml"));
|
||||
var frebEvents = new List<FrebLogItem>();
|
||||
|
||||
foreach (var xmlFile in xmlFiles)
|
||||
{
|
||||
var xDocument = XDocument.Load(xmlFile).Root;
|
||||
var nameSpace = (XNamespace)"http://schemas.microsoft.com/win/2004/08/events/event";
|
||||
var eventElements = xDocument.Descendants(nameSpace + "Event");
|
||||
foreach (var eventElement in eventElements)
|
||||
{
|
||||
var eventElementWithOpCode = eventElement.Descendants(nameSpace + "RenderingInfo").Single().Descendants(nameSpace + "Opcode").Single();
|
||||
var requestStatus = eventElement.Element(nameSpace + "EventData").Descendants().Where(el => el.Attribute("Name").Value == "requestStatus").SingleOrDefault();
|
||||
frebEvents.Add(new FrebLogItem(eventElementWithOpCode.Value, requestStatus?.Value));
|
||||
}
|
||||
}
|
||||
|
||||
return frebEvents;
|
||||
}
|
||||
|
||||
public class FrebLogItem
|
||||
{
|
||||
private string _opCode;
|
||||
private string _requestStatus;
|
||||
|
||||
public FrebLogItem(string opCode)
|
||||
{
|
||||
_opCode = opCode;
|
||||
}
|
||||
|
||||
public FrebLogItem(string opCode, string requestStatus)
|
||||
{
|
||||
_opCode = opCode;
|
||||
_requestStatus = requestStatus;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var item = obj as FrebLogItem;
|
||||
return item != null &&
|
||||
_opCode == item._opCode &&
|
||||
_requestStatus == item._requestStatus;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(_opCode, _requestStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class HelloWorldInProcessTests
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public HelloWorldInProcessTests(IISTestSiteFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task HelloWorld_InProcess()
|
||||
{
|
||||
Assert.Equal("Hello World", await _fixture.Client.GetStringAsync("/HelloWorld"));
|
||||
|
||||
Assert.Equal("/Path??", await _fixture.Client.GetStringAsync("/HelloWorld/Path%3F%3F?query"));
|
||||
|
||||
Assert.Equal("?query", await _fixture.Client.GetStringAsync("/HelloWorld/Query%3F%3F?query"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class HostingEnvironmentTests: FixtureLoggedTest
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public HostingEnvironmentTests(IISTestSiteFixture fixture): base(fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.ShutdownToken)]
|
||||
public async Task HostingEnvironmentIsCorrect()
|
||||
{
|
||||
Assert.Equal(
|
||||
$"ContentRootPath {_fixture.DeploymentResult.ContentRoot}" + Environment.NewLine +
|
||||
$"WebRootPath {_fixture.DeploymentResult.ContentRoot}\\wwwroot" + Environment.NewLine +
|
||||
$"CurrentDirectory {Path.GetDirectoryName(_fixture.DeploymentResult.HostProcess.MainModule.FileName)}",
|
||||
await _fixture.Client.GetStringAsync("/HostingEnvironment"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class InvalidReadWriteOperationTests
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public InvalidReadWriteOperationTests(IISTestSiteFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task TestReadOffsetWorks()
|
||||
{
|
||||
var result = await _fixture.Client.PostAsync($"/TestReadOffsetWorks", new StringContent("Hello World"));
|
||||
Assert.Equal("Hello World", await result.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("/InvalidOffsetSmall")]
|
||||
[InlineData("/InvalidOffsetLarge")]
|
||||
[InlineData("/InvalidCountSmall")]
|
||||
[InlineData("/InvalidCountLarge")]
|
||||
[InlineData("/InvalidCountWithOffset")]
|
||||
public async Task TestInvalidReadOperations(string operation)
|
||||
{
|
||||
var result = await _fixture.Client.GetStringAsync($"/TestInvalidReadOperations{operation}");
|
||||
Assert.Equal("Success", result);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("/NullBuffer")]
|
||||
[InlineData("/InvalidCountZeroRead")]
|
||||
public async Task TestValidReadOperations(string operation)
|
||||
{
|
||||
var result = await _fixture.Client.GetStringAsync($"/TestValidReadOperations{operation}");
|
||||
Assert.Equal("Success", result);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("/NullBufferPost")]
|
||||
[InlineData("/InvalidCountZeroReadPost")]
|
||||
public async Task TestValidReadOperationsPost(string operation)
|
||||
{
|
||||
var result = await _fixture.Client.PostAsync($"/TestValidReadOperations{operation}", new StringContent("hello"));
|
||||
Assert.Equal("Success", await result.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("/InvalidOffsetSmall")]
|
||||
[InlineData("/InvalidOffsetLarge")]
|
||||
[InlineData("/InvalidCountSmall")]
|
||||
[InlineData("/InvalidCountLarge")]
|
||||
[InlineData("/InvalidCountWithOffset")]
|
||||
public async Task TestInvalidWriteOperations(string operation)
|
||||
{
|
||||
var result = await _fixture.Client.GetStringAsync($"/TestInvalidWriteOperations{operation}");
|
||||
Assert.Equal("Success", result);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task TestValidWriteOperations()
|
||||
{
|
||||
var result = await _fixture.Client.GetStringAsync($"/TestValidWriteOperations/NullBuffer");
|
||||
Assert.Equal("Success", result);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task TestValidWriteOperationsPost()
|
||||
{
|
||||
var result = await _fixture.Client.PostAsync($"/TestValidWriteOperations/NullBufferPost", new StringContent("hello"));
|
||||
Assert.Equal("Success", await result.Content.ReadAsStringAsync());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class LargeResponseBodyTests
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public LargeResponseBodyTests(IISTestSiteFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(65000)]
|
||||
[InlineData(1000000)]
|
||||
[InlineData(10000000)]
|
||||
[InlineData(100000000)]
|
||||
public async Task LargeResponseBodyTest_CheckAllResponseBodyBytesWritten(int query)
|
||||
{
|
||||
Assert.Equal(new string('a', query), await _fixture.Client.GetStringAsync($"/LargeResponseBody?length={query}"));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task LargeResponseBodyFromFile_CheckAllResponseBodyBytesWritten()
|
||||
{
|
||||
Assert.Equal(200000000, (await _fixture.Client.GetStringAsync($"/LargeResponseFile")).Length);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class LogPipeTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public LogPipeTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("ConsoleErrorWrite")]
|
||||
[InlineData("ConsoleWrite")]
|
||||
public async Task CheckStdoutLoggingToPipe_DoesNotCrashProcess(string path)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await Helpers.AssertStarts(deploymentResult, path);
|
||||
|
||||
StopServer();
|
||||
|
||||
if (deploymentParameters.ServerType == ServerType.IISExpress)
|
||||
{
|
||||
Assert.Contains(TestSink.Writes, context => context.Message.Contains("TEST MESSAGE"));
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("ConsoleErrorWriteStartServer")]
|
||||
[InlineData("ConsoleWriteStartServer")]
|
||||
public async Task CheckStdoutLoggingToPipeWithFirstWrite(string path)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
|
||||
var firstWriteString = "TEST MESSAGE";
|
||||
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} {path}");
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await Helpers.AssertStarts(deploymentResult);
|
||||
|
||||
StopServer();
|
||||
|
||||
if (deploymentParameters.ServerType == ServerType.IISExpress)
|
||||
{
|
||||
// We can't read stdout logs from IIS as they aren't redirected.
|
||||
Assert.Contains(TestSink.Writes, context => context.Message.Contains(firstWriteString));
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task CheckUnicodePipe()
|
||||
{
|
||||
var path = "CheckConsoleFunctions";
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} {path}");
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync(path);
|
||||
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
|
||||
StopServer();
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessThreadExitStdOut(deploymentResult, "12", "(.*)彡⾔(.*)"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class ResponseHeaders
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public ResponseHeaders(IISTestSiteFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task AddResponseHeaders_HeaderValuesAreSetCorrectly()
|
||||
{
|
||||
var response = await _fixture.Client.GetAsync("ResponseHeaders");
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("Request Complete", responseText);
|
||||
|
||||
Assert.True(response.Headers.TryGetValues("UnknownHeader", out var headerValues));
|
||||
Assert.Equal("test123=foo", headerValues.First());
|
||||
|
||||
Assert.True(response.Content.Headers.TryGetValues(HeaderNames.ContentType, out headerValues));
|
||||
Assert.Equal("text/plain", headerValues.First());
|
||||
|
||||
Assert.True(response.Headers.TryGetValues("MultiHeader", out headerValues));
|
||||
Assert.Equal(2, headerValues.Count());
|
||||
Assert.Equal("1", headerValues.First());
|
||||
Assert.Equal("2", headerValues.Last());
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ErrorCodeIsSetForExceptionDuringRequest()
|
||||
{
|
||||
var response = await _fixture.Client.GetAsync("Throw");
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
Assert.Equal("Internal Server Error", response.ReasonPhrase);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(200, "custom", "custom", null)]
|
||||
[InlineData(200, "custom", "custom", "Custom body")]
|
||||
[InlineData(200, "custom", "custom", "")]
|
||||
|
||||
|
||||
[InlineData(500, "", "Internal Server Error", null)]
|
||||
[InlineData(500, "", "Internal Server Error", "Custom body")]
|
||||
[InlineData(500, "", "Internal Server Error", "")]
|
||||
|
||||
[InlineData(400, "custom", "custom", null)]
|
||||
[InlineData(400, "", "Bad Request", "Custom body")]
|
||||
[InlineData(400, "", "Bad Request", "")]
|
||||
|
||||
[InlineData(999, "", "", null)]
|
||||
[InlineData(999, "", "", "Custom body")]
|
||||
[InlineData(999, "", "", "")]
|
||||
public async Task CustomErrorCodeWorks(int code, string reason, string expectedReason, string body)
|
||||
{
|
||||
var response = await _fixture.Client.GetAsync($"SetCustomErorCode?code={code}&reason={reason}&writeBody={body != null}&body={body}");
|
||||
Assert.Equal((HttpStatusCode)code, response.StatusCode);
|
||||
Assert.Equal(expectedReason, response.ReasonPhrase);
|
||||
|
||||
// ReadAsStringAsync returns empty string for empty results
|
||||
Assert.Equal(body ?? string.Empty, await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ServerHeaderIsOverriden()
|
||||
{
|
||||
var response = await _fixture.Client.GetAsync("OverrideServer");
|
||||
Assert.Equal("MyServer/7.8", response.Headers.Server.Single().Product.ToString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class ResponseInvalidOrderingTest
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public ResponseInvalidOrderingTest(IISTestSiteFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("SetStatusCodeAfterWrite")]
|
||||
[InlineData("SetHeaderAfterWrite")]
|
||||
public async Task ResponseInvalidOrderingTests_ExpectFailure(string path)
|
||||
{
|
||||
Assert.Equal($"Started_{path}Threw_Finished", await _fixture.Client.GetStringAsync("/ResponseInvalidOrdering/" + path));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class ServerVariablesTest
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public ServerVariablesTest(IISTestSiteFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ProvidesAccessToServerVariables()
|
||||
{
|
||||
var port = _fixture.Client.BaseAddress.Port;
|
||||
Assert.Equal("SERVER_PORT: " + port, await _fixture.Client.GetStringAsync("/ServerVariable?q=SERVER_PORT"));
|
||||
Assert.Equal("QUERY_STRING: q=QUERY_STRING", await _fixture.Client.GetStringAsync("/ServerVariable?q=QUERY_STRING"));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ReturnsNullForUndefinedServerVariable()
|
||||
{
|
||||
Assert.Equal("THIS_VAR_IS_UNDEFINED: (null)", await _fixture.Client.GetStringAsync("/ServerVariable?q=THIS_VAR_IS_UNDEFINED"));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task CanSetAndReadVariable()
|
||||
{
|
||||
Assert.Equal("ROUNDTRIP: 1", await _fixture.Client.GetStringAsync("/ServerVariable?v=1&q=ROUNDTRIP"));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task BasePathIsNotPrefixedBySlashSlashQuestionMark()
|
||||
{
|
||||
Assert.DoesNotContain(@"\\?\", await _fixture.Client.GetStringAsync("/BasePath"));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task GetServerVariableDoesNotCrash()
|
||||
{
|
||||
await Helpers.StressLoad(_fixture.Client, "/GetServerVariableStress", response => {
|
||||
var text = response.Content.ReadAsStringAsync().Result;
|
||||
Assert.StartsWith("Response Begin", text);
|
||||
Assert.EndsWith("Response End", text);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class StartupExceptionTests : LogFileTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public StartupExceptionTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("CheckLargeStdErrWrites")]
|
||||
[InlineData("CheckLargeStdOutWrites")]
|
||||
[InlineData("CheckOversizedStdErrWrites")]
|
||||
[InlineData("CheckOversizedStdOutWrites")]
|
||||
public async Task CheckStdoutWithLargeWrites_TestSink(string mode)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} {mode}");
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await AssertFailsToStart(deploymentResult);
|
||||
var expectedString = new string('a', 30000);
|
||||
Assert.Contains(TestSink.Writes, context => context.Message.Contains(expectedString));
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessThreadExitStdOut(deploymentResult, "12", expectedString));
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("CheckLargeStdErrWrites")]
|
||||
[InlineData("CheckLargeStdOutWrites")]
|
||||
[InlineData("CheckOversizedStdErrWrites")]
|
||||
[InlineData("CheckOversizedStdOutWrites")]
|
||||
public async Task CheckStdoutWithLargeWrites_LogFile(string mode)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} {mode}");
|
||||
deploymentParameters.EnableLogging(_logFolderPath);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await AssertFailsToStart(deploymentResult);
|
||||
|
||||
var contents = GetLogFileContent(deploymentResult);
|
||||
var expectedString = new string('a', 30000);
|
||||
|
||||
Assert.Contains(expectedString, contents);
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessThreadExitStdOut(deploymentResult, "12", expectedString));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task CheckValidConsoleFunctions()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} CheckConsoleFunctions");
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await AssertFailsToStart(deploymentResult);
|
||||
|
||||
Assert.Contains(TestSink.Writes, context => context.Message.Contains("Is Console redirection: True"));
|
||||
}
|
||||
|
||||
private async Task AssertFailsToStart(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
||||
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
|
||||
StopServer();
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task Gets500_30_ErrorPage()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} EarlyReturn");
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
||||
Assert.False(response.IsSuccessStatusCode);
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Contains("500.30 - ANCM In-Process Start Failure", responseText);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,479 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class StartupTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public StartupTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
private readonly string _dotnetLocation = DotNetCommands.GetDotNetExecutable(RuntimeArchitecture.x64);
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
public async Task ExpandEnvironmentVariableInWebConfig()
|
||||
{
|
||||
// Point to dotnet installed in user profile.
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
deploymentParameters.EnvironmentVariables["DotnetPath"] = _dotnetLocation;
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", "%DotnetPath%"));
|
||||
await StartAsync(deploymentParameters);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("bogus", "", @"Executable was not found at '.*?\\bogus.exe")]
|
||||
[InlineData("c:\\random files\\dotnet.exe", "something.dll", @"Could not find dotnet.exe at '.*?\\dotnet.exe'")]
|
||||
[InlineData(".\\dotnet.exe", "something.dll", @"Could not find dotnet.exe at '.*?\\.\\dotnet.exe'")]
|
||||
[InlineData("dotnet.exe", "", @"Application arguments are empty.")]
|
||||
[InlineData("dotnet.zip", "", @"Process path 'dotnet.zip' doesn't have '.exe' extension.")]
|
||||
public async Task InvalidProcessPath_ExpectServerError(string path, string arguments, string subError)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", path));
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("arguments", arguments));
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("HelloWorld");
|
||||
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, $@"Application '{Regex.Escape(deploymentResult.ContentRoot)}\\' wasn't able to start. {subError}");
|
||||
|
||||
Assert.Contains("HTTP Error 500.0 - ANCM In-Process Handler Load Failure", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task StartsWithDotnetLocationWithoutExe()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
|
||||
var dotnetLocationWithoutExtension = _dotnetLocation.Substring(0, _dotnetLocation.LastIndexOf("."));
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", dotnetLocationWithoutExtension));
|
||||
|
||||
await StartAsync(deploymentParameters);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task StartsWithDotnetLocationUppercase()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
|
||||
var dotnetLocationWithoutExtension = _dotnetLocation.Substring(0, _dotnetLocation.LastIndexOf(".")).ToUpperInvariant();
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", dotnetLocationWithoutExtension));
|
||||
|
||||
await StartAsync(deploymentParameters);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("dotnet")]
|
||||
[InlineData("dotnet.EXE")]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
public async Task StartsWithDotnetOnThePath(string path)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
|
||||
deploymentParameters.EnvironmentVariables["PATH"] = Path.GetDirectoryName(_dotnetLocation);
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", path));
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
await deploymentResult.AssertStarts();
|
||||
|
||||
StopServer();
|
||||
// Verify that in this scenario where.exe was invoked only once by shim and request handler uses cached value
|
||||
Assert.Equal(1, TestSink.Writes.Count(w => w.Message.Contains("Invoking where.exe to find dotnet.exe")));
|
||||
}
|
||||
|
||||
public static TestMatrix TestVariants
|
||||
=> TestMatrix.ForServers(DeployerSelector.ServerType)
|
||||
.WithTfms(Tfm.NetCoreApp22)
|
||||
.WithAllApplicationTypes()
|
||||
.WithAncmV2InProcess();
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task HelloWorld(TestVariant variant)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
await StartAsync(deploymentParameters);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
public async Task StartsWithPortableAndBootstraperExe()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
// We need the right dotnet on the path in IIS
|
||||
deploymentParameters.EnvironmentVariables["PATH"] = Path.GetDirectoryName(DotNetCommands.GetDotNetExecutable(deploymentParameters.RuntimeArchitecture));
|
||||
|
||||
// rest publisher as it doesn't support additional parameters
|
||||
deploymentParameters.ApplicationPublisher = null;
|
||||
// ReferenceTestTasks is workaround for https://github.com/dotnet/sdk/issues/2482
|
||||
deploymentParameters.AdditionalPublishParameters = "-p:RuntimeIdentifier=win7-x64 -p:UseAppHost=true -p:SelfContained=false -p:ReferenceTestTasks=false";
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
Assert.True(File.Exists(Path.Combine(deploymentResult.ContentRoot, "InProcessWebSite.exe")));
|
||||
Assert.False(File.Exists(Path.Combine(deploymentResult.ContentRoot, "hostfxr.dll")));
|
||||
Assert.Contains("InProcessWebSite.exe", Helpers.ReadAllTextFromFile(Path.Combine(deploymentResult.ContentRoot, "web.config"), Logger));
|
||||
|
||||
await deploymentResult.AssertStarts();
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task DetectsOverriddenServer()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} OverriddenServer");
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/");
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvents(deploymentResult,
|
||||
EventLogHelpers.InProcessFailedToStart(deploymentResult, "CLR worker thread exited prematurely"),
|
||||
EventLogHelpers.InProcessThreadException(deploymentResult, ".*?Application is running inside IIS process but is not configured to use IIS server"));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task LogsStartupExceptionExitError()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} Throw");
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/");
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvents(deploymentResult,
|
||||
EventLogHelpers.InProcessFailedToStart(deploymentResult, "CLR worker thread exited prematurely"),
|
||||
EventLogHelpers.InProcessThreadException(deploymentResult, ", exception code = '0xe0434352'"));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task LogsUnexpectedThreadExitError()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} EarlyReturn");
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvents(deploymentResult,
|
||||
EventLogHelpers.InProcessFailedToStart(deploymentResult, "CLR worker thread exited prematurely"),
|
||||
EventLogHelpers.InProcessThreadExit(deploymentResult, "12"));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RemoveHostfxrFromApp_InProcessHostfxrInvalid()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.ApplicationType = ApplicationType.Standalone;
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
File.Copy(
|
||||
Path.Combine(deploymentResult.ContentRoot, "aspnetcorev2_inprocess.dll"),
|
||||
Path.Combine(deploymentResult.ContentRoot, "hostfxr.dll"),
|
||||
true);
|
||||
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessHostfxrInvalid(deploymentResult), Logger);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task TargedDifferenceSharedFramework_FailedToFindNativeDependencies()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
Helpers.ModifyFrameworkVersionInRuntimeConfig(deploymentResult);
|
||||
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessFailedToFindNativeDependencies(deploymentResult), Logger);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RemoveInProcessReference_FailedToFindRequestHandler()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.ApplicationType = ApplicationType.Standalone;
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
File.Delete(Path.Combine(deploymentResult.ContentRoot, "aspnetcorev2_inprocess.dll"));
|
||||
|
||||
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
|
||||
|
||||
if (DeployerSelector.IsForwardsCompatibilityTest)
|
||||
{
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessFailedToFindNativeDependencies(deploymentResult), Logger);
|
||||
}
|
||||
else
|
||||
{
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessFailedToFindRequestHandler(deploymentResult), Logger);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task StartupTimeoutIsApplied()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} Hang");
|
||||
deploymentParameters.WebConfigActionList.Add(
|
||||
WebConfigHelpers.AddOrModifyAspNetCoreSection("startupTimeLimit", "1"));
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/");
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvents(deploymentResult,
|
||||
EventLogHelpers.InProcessFailedToStart(deploymentResult, "Managed server didn't initialize after 1000 ms.")
|
||||
);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ShutdownTimeoutIsApplied()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} HangOnStop");
|
||||
deploymentParameters.WebConfigActionList.Add(
|
||||
WebConfigHelpers.AddOrModifyAspNetCoreSection("shutdownTimeLimit", "1"));
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
Assert.Equal("Hello World", await deploymentResult.HttpClient.GetStringAsync("/HelloWorld"));
|
||||
|
||||
StopServer();
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvents(deploymentResult,
|
||||
EventLogHelpers.InProcessStarted(deploymentResult),
|
||||
EventLogHelpers.InProcessFailedToStop(deploymentResult, ""));
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task CheckInvalidHostingModelParameter()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("hostingModel", "bogus"));
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("HelloWorld");
|
||||
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvents(deploymentResult,
|
||||
EventLogHelpers.ConfigurationLoadError(deploymentResult, "Unknown hosting model 'bogus'. Please specify either hostingModel=\"inprocess\" or hostingModel=\"outofprocess\" in the web.config file.")
|
||||
);
|
||||
}
|
||||
|
||||
private static Dictionary<string, (string, Action<XElement>)> InvalidConfigTransformations = InitInvalidConfigTransformations();
|
||||
public static IEnumerable<object[]> InvalidConfigTransformationsScenarios => InvalidConfigTransformations.ToTheoryData();
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(InvalidConfigTransformationsScenarios))]
|
||||
public async Task ReportsWebConfigAuthoringErrors(string scenario)
|
||||
{
|
||||
var (expectedError, action) = InvalidConfigTransformations[scenario];
|
||||
var iisDeploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
iisDeploymentParameters.WebConfigActionList.Add((element, _) => action(element));
|
||||
var deploymentResult = await DeployAsync(iisDeploymentParameters);
|
||||
var result = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, result.StatusCode);
|
||||
|
||||
// Config load errors might not allow us to initialize log file
|
||||
deploymentResult.AllowNoLogs();
|
||||
|
||||
StopServer();
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvents(deploymentResult,
|
||||
EventLogHelpers.ConfigurationLoadError(deploymentResult, expectedError)
|
||||
);
|
||||
}
|
||||
|
||||
public static Dictionary<string, (string, Action<XElement>)> InitInvalidConfigTransformations()
|
||||
{
|
||||
var dictionary = new Dictionary<string, (string, Action<XElement>)>();
|
||||
dictionary.Add("Empty process path",
|
||||
(
|
||||
"Attribute 'processPath' is required.",
|
||||
element => element.Descendants("aspNetCore").Single().SetAttributeValue("processPath", "")
|
||||
));
|
||||
dictionary.Add("Unknown hostingModel",
|
||||
(
|
||||
"Unknown hosting model 'asdf'.",
|
||||
element => element.Descendants("aspNetCore").Single().SetAttributeValue("hostingModel", "asdf")
|
||||
));
|
||||
dictionary.Add("environmentVariables with add",
|
||||
(
|
||||
"Unable to get required configuration section 'system.webServer/aspNetCore'. Possible reason is web.config authoring error.",
|
||||
element => element.Descendants("aspNetCore").Single().GetOrAdd("environmentVariables").GetOrAdd("add")
|
||||
));
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
private static Dictionary<string, Func<IISDeploymentParameters, string>> PortableConfigTransformations = InitPortableWebConfigTransformations();
|
||||
public static IEnumerable<object[]> PortableConfigTransformationsScenarios => PortableConfigTransformations.ToTheoryData();
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(PortableConfigTransformationsScenarios))]
|
||||
public async Task StartsWithWebConfigVariationsPortable(string scenario)
|
||||
{
|
||||
var action = PortableConfigTransformations[scenario];
|
||||
var iisDeploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
var expectedArguments = action(iisDeploymentParameters);
|
||||
var result = await DeployAsync(iisDeploymentParameters);
|
||||
Assert.Equal(expectedArguments, await result.HttpClient.GetStringAsync("/CommandLineArgs"));
|
||||
}
|
||||
|
||||
public static Dictionary<string, Func<IISDeploymentParameters, string>> InitPortableWebConfigTransformations()
|
||||
{
|
||||
var dictionary = new Dictionary<string, Func<IISDeploymentParameters, string>>();
|
||||
var pathWithSpace = "\u03c0 \u2260 3\u00b714";
|
||||
|
||||
dictionary.Add("App in bin subdirectory full path to dll using exec and quotes",
|
||||
parameters => {
|
||||
MoveApplication(parameters, "bin");
|
||||
parameters.TransformArguments((arguments, root) => "exec " + Path.Combine(root, "bin", arguments));
|
||||
return "";
|
||||
});
|
||||
|
||||
dictionary.Add("App in subdirectory with space",
|
||||
parameters => {
|
||||
MoveApplication(parameters, pathWithSpace);
|
||||
parameters.TransformArguments((arguments, root) => Path.Combine(pathWithSpace, arguments));
|
||||
return "";
|
||||
});
|
||||
|
||||
dictionary.Add("App in subdirectory with space and full path to dll",
|
||||
parameters => {
|
||||
MoveApplication(parameters, pathWithSpace);
|
||||
parameters.TransformArguments((arguments, root) => Path.Combine(root, pathWithSpace, arguments));
|
||||
return "";
|
||||
});
|
||||
|
||||
dictionary.Add("App in bin subdirectory with space full path to dll using exec and quotes",
|
||||
parameters => {
|
||||
MoveApplication(parameters, pathWithSpace);
|
||||
parameters.TransformArguments((arguments, root) => "exec \"" + Path.Combine(root, pathWithSpace, arguments) + "\" extra arguments");
|
||||
return "extra|arguments";
|
||||
});
|
||||
|
||||
dictionary.Add("App in bin subdirectory and quoted argument",
|
||||
parameters => {
|
||||
MoveApplication(parameters, "bin");
|
||||
parameters.TransformArguments((arguments, root) => Path.Combine("bin", arguments) + " \"extra argument\"");
|
||||
return "extra argument";
|
||||
});
|
||||
|
||||
dictionary.Add("App in bin subdirectory full path to dll",
|
||||
parameters => {
|
||||
MoveApplication(parameters, "bin");
|
||||
parameters.TransformArguments((arguments, root) => Path.Combine(root, "bin", arguments) + " extra arguments");
|
||||
return "extra|arguments";
|
||||
});
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
|
||||
private static Dictionary<string, Func<IISDeploymentParameters, string>> StandaloneConfigTransformations = InitStandaloneConfigTransformations();
|
||||
public static IEnumerable<object[]> StandaloneConfigTransformationsScenarios => StandaloneConfigTransformations.ToTheoryData();
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(StandaloneConfigTransformationsScenarios))]
|
||||
public async Task StartsWithWebConfigVariationsStandalone(string scenario)
|
||||
{
|
||||
var action = StandaloneConfigTransformations[scenario];
|
||||
var iisDeploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true);
|
||||
iisDeploymentParameters.ApplicationType = ApplicationType.Standalone;
|
||||
var expectedArguments = action(iisDeploymentParameters);
|
||||
var result = await DeployAsync(iisDeploymentParameters);
|
||||
Assert.Equal(expectedArguments, await result.HttpClient.GetStringAsync("/CommandLineArgs"));
|
||||
}
|
||||
|
||||
public static Dictionary<string, Func<IISDeploymentParameters, string>> InitStandaloneConfigTransformations()
|
||||
{
|
||||
var dictionary = new Dictionary<string, Func<IISDeploymentParameters, string>>();
|
||||
var pathWithSpace = "\u03c0 \u2260 3\u00b714";
|
||||
|
||||
dictionary.Add("App in subdirectory",
|
||||
parameters => {
|
||||
MoveApplication(parameters, pathWithSpace);
|
||||
parameters.TransformPath((path, root) => Path.Combine(pathWithSpace, path));
|
||||
parameters.TransformArguments((arguments, root) => "\"additional argument\"");
|
||||
return "additional argument";
|
||||
});
|
||||
|
||||
dictionary.Add("App in bin subdirectory full path",
|
||||
parameters => {
|
||||
MoveApplication(parameters, pathWithSpace);
|
||||
parameters.TransformPath((path, root) => Path.Combine(root, pathWithSpace, path));
|
||||
parameters.TransformArguments((arguments, root) => "additional arguments");
|
||||
return "additional|arguments";
|
||||
});
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
private static void MoveApplication(
|
||||
IISDeploymentParameters parameters,
|
||||
string subdirectory)
|
||||
{
|
||||
parameters.WebConfigActionList.Add((config, contentRoot) =>
|
||||
{
|
||||
var source = new DirectoryInfo(contentRoot);
|
||||
var subDirectoryPath = source.CreateSubdirectory(subdirectory);
|
||||
|
||||
// Copy everything into a subfolder
|
||||
Helpers.CopyFiles(source, subDirectoryPath, null);
|
||||
// Cleanup files
|
||||
foreach (var fileSystemInfo in source.GetFiles())
|
||||
{
|
||||
fileSystemInfo.Delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async Task AssertSiteFailsToStartWithInProcessStaticContent(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
Assert.Contains("HTTP Error 500.0 - ANCM In-Process Handler Load Failure", await response.Content.ReadAsStringAsync());
|
||||
StopServer();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class SynchronousReadAndWriteTests: FixtureLoggedTest
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public SynchronousReadAndWriteTests(IISTestSiteFixture fixture): base(fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ReadAndWriteSynchronously()
|
||||
{
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
var content = new StringContent(new string('a', 100000));
|
||||
var response = await _fixture.Client.PostAsync("ReadAndWriteSynchronously", content);
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.Equal(expected: 110000, actual: responseText.Length);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ReadAndWriteEcho()
|
||||
{
|
||||
var body = new string('a', 100000);
|
||||
var content = new StringContent(body);
|
||||
var response = await _fixture.Client.PostAsync("ReadAndWriteEcho", content);
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.Equal(body, responseText);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ReadAndWriteCopyToAsync()
|
||||
{
|
||||
var body = new string('a', 100000);
|
||||
var content = new StringContent(body);
|
||||
var response = await _fixture.Client.PostAsync("ReadAndWriteCopyToAsync", content);
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.Equal(body, responseText);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ReadAndWriteEchoTwice()
|
||||
{
|
||||
var requestBody = new string('a', 10000);
|
||||
var content = new StringContent(requestBody);
|
||||
var response = await _fixture.Client.PostAsync("ReadAndWriteEchoTwice", content);
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.Equal(requestBody.Length * 2, responseText.Length);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ReadSetHeaderWrite()
|
||||
{
|
||||
var body = "Body text";
|
||||
var content = new StringContent(body);
|
||||
var response = await _fixture.Client.PostAsync("SetHeaderFromBody", content);
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.Equal(body, response.Headers.GetValues("BodyAsString").Single());
|
||||
Assert.Equal(body, responseText);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ReadAndWriteSlowConnection()
|
||||
{
|
||||
using (var connection = _fixture.CreateTestConnection())
|
||||
{
|
||||
var testString = "hello world";
|
||||
var request = $"POST /ReadAndWriteSlowConnection HTTP/1.0\r\n" +
|
||||
$"Content-Length: {testString.Length}\r\n" +
|
||||
"Host: " + "localhost\r\n" +
|
||||
"\r\n" + testString;
|
||||
|
||||
foreach (var c in request)
|
||||
{
|
||||
await connection.Send(c.ToString());
|
||||
await Task.Delay(10);
|
||||
}
|
||||
|
||||
await connection.Receive(
|
||||
"HTTP/1.1 200 OK",
|
||||
"");
|
||||
await connection.ReceiveHeaders();
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
foreach (var c in testString)
|
||||
{
|
||||
await connection.Receive(c.ToString());
|
||||
}
|
||||
await Task.Delay(10);
|
||||
}
|
||||
await connection.WaitForConnectionClose();
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ReadAndWriteInterleaved()
|
||||
{
|
||||
using (var connection = _fixture.CreateTestConnection())
|
||||
{
|
||||
var requestLength = 0;
|
||||
var messages = new List<string>();
|
||||
for (var i = 1; i < 100; i++)
|
||||
{
|
||||
var message = i + Environment.NewLine;
|
||||
requestLength += message.Length;
|
||||
messages.Add(message);
|
||||
}
|
||||
|
||||
await connection.Send(
|
||||
"POST /ReadAndWriteEchoLines HTTP/1.0",
|
||||
$"Content-Length: {requestLength}",
|
||||
"Host: localhost",
|
||||
"",
|
||||
"");
|
||||
|
||||
await connection.Receive(
|
||||
"HTTP/1.1 200 OK",
|
||||
"");
|
||||
await connection.ReceiveHeaders();
|
||||
|
||||
foreach (var message in messages)
|
||||
{
|
||||
await connection.Send(message);
|
||||
await connection.Receive(message);
|
||||
}
|
||||
|
||||
await connection.Send("\r\n");
|
||||
await connection.WaitForConnectionClose();
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ConsumePartialBody()
|
||||
{
|
||||
using (var connection = _fixture.CreateTestConnection())
|
||||
{
|
||||
var message = "Hello";
|
||||
await connection.Send(
|
||||
"POST /ReadPartialBody HTTP/1.1",
|
||||
$"Content-Length: {100}",
|
||||
"Host: localhost",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
|
||||
await connection.Send(message);
|
||||
|
||||
await connection.Receive(
|
||||
"HTTP/1.1 200 OK",
|
||||
"");
|
||||
|
||||
// This test can return both content length or chunked response
|
||||
// depending on if appfunc managed to complete before write was
|
||||
// issued
|
||||
var headers = await connection.ReceiveHeaders();
|
||||
if (headers.Contains("Content-Length: 5"))
|
||||
{
|
||||
await connection.Receive("Hello");
|
||||
}
|
||||
else
|
||||
{
|
||||
await connection.Receive(
|
||||
"5",
|
||||
message,
|
||||
"");
|
||||
await connection.Receive(
|
||||
"0",
|
||||
"",
|
||||
"");
|
||||
}
|
||||
|
||||
await connection.WaitForConnectionClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,242 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class LoggingTests : LogFileTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public LoggingTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
public static TestMatrix TestVariants
|
||||
=> TestMatrix.ForServers(DeployerSelector.ServerType)
|
||||
.WithTfms(Tfm.NetCoreApp22)
|
||||
.WithAllApplicationTypes()
|
||||
.WithAncmVersions(AncmVersion.AspNetCoreModuleV2)
|
||||
.WithAllHostingModels();
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task CheckStdoutLoggingToFile(TestVariant variant)
|
||||
{
|
||||
await CheckStdoutToFile(variant, "ConsoleWrite");
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task CheckStdoutErrLoggingToFile(TestVariant variant)
|
||||
{
|
||||
await CheckStdoutToFile(variant, "ConsoleErrorWrite");
|
||||
}
|
||||
|
||||
private async Task CheckStdoutToFile(TestVariant variant, string path)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
deploymentParameters.EnableLogging(_logFolderPath);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await Helpers.AssertStarts(deploymentResult, path);
|
||||
|
||||
StopServer();
|
||||
|
||||
var contents = Helpers.ReadAllTextFromFile(Helpers.GetExpectedLogName(deploymentResult, _logFolderPath), Logger);
|
||||
|
||||
Assert.Contains("TEST MESSAGE", contents);
|
||||
}
|
||||
|
||||
// Move to separate file
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task InvalidFilePathForLogs_ServerStillRuns(TestVariant variant)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
|
||||
deploymentParameters.WebConfigActionList.Add(
|
||||
WebConfigHelpers.AddOrModifyAspNetCoreSection("stdoutLogEnabled", "true"));
|
||||
deploymentParameters.WebConfigActionList.Add(
|
||||
WebConfigHelpers.AddOrModifyAspNetCoreSection("stdoutLogFile", Path.Combine("Q:", "std")));
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await Helpers.AssertStarts(deploymentResult, "HelloWorld");
|
||||
|
||||
StopServer();
|
||||
if (variant.HostingModel == HostingModel.InProcess)
|
||||
{
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Could not start stdout redirection in (.*)aspnetcorev2.dll. Exception message: HRESULT 0x80070003");
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Could not stop stdout redirection in (.*)aspnetcorev2.dll. Exception message: HRESULT 0x80070002");
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task StartupMessagesAreLoggedIntoDebugLogFile(TestVariant variant)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
deploymentParameters.HandlerSettings["debugLevel"] = "file";
|
||||
deploymentParameters.HandlerSettings["debugFile"] = "debug.txt";
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await deploymentResult.HttpClient.GetAsync("/");
|
||||
|
||||
AssertLogs(Path.Combine(deploymentResult.ContentRoot, "debug.txt"));
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task StartupMessagesAreLoggedIntoDefaultDebugLogFile(TestVariant variant)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
deploymentParameters.HandlerSettings["debugLevel"] = "file";
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await deploymentResult.HttpClient.GetAsync("/");
|
||||
|
||||
AssertLogs(Path.Combine(deploymentResult.ContentRoot, "aspnetcore-debug.log"));
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task StartupMessagesAreLoggedIntoDefaultDebugLogFileWhenEnabledWithEnvVar(TestVariant variant)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
deploymentParameters.EnvironmentVariables["ASPNETCORE_MODULE_DEBUG"] = "file";
|
||||
// Add empty debugFile handler setting to prevent IIS deployer from overriding debug settings
|
||||
deploymentParameters.HandlerSettings["debugFile"] = "";
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
await deploymentResult.HttpClient.GetAsync("/");
|
||||
|
||||
AssertLogs(Path.Combine(deploymentResult.ContentRoot, "aspnetcore-debug.log"));
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task StartupMessagesLogFileSwitchedWhenLogFilePresentInWebConfig(TestVariant variant)
|
||||
{
|
||||
var firstTempFile = Path.GetTempFileName();
|
||||
var secondTempFile = Path.GetTempFileName();
|
||||
|
||||
try
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
deploymentParameters.EnvironmentVariables["ASPNETCORE_MODULE_DEBUG_FILE"] = firstTempFile;
|
||||
deploymentParameters.AddDebugLogToWebConfig(secondTempFile);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/");
|
||||
|
||||
StopServer();
|
||||
var logContents = Helpers.ReadAllTextFromFile(firstTempFile, Logger);
|
||||
|
||||
Assert.Contains("Switching debug log files to", logContents);
|
||||
|
||||
AssertLogs(secondTempFile);
|
||||
}
|
||||
finally
|
||||
{
|
||||
File.Delete(firstTempFile);
|
||||
File.Delete(secondTempFile);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
|
||||
public async Task DebugLogsAreWrittenToEventLog(TestVariant variant)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
deploymentParameters.HandlerSettings["debugLevel"] = "file,eventlog";
|
||||
var deploymentResult = await StartAsync(deploymentParameters);
|
||||
StopServer();
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, @"\[aspnetcorev2.dll\] Initializing logs for .*?Description: IIS ASP.NET Core Module V2");
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task CheckUTF8File(TestVariant variant)
|
||||
{
|
||||
var path = "CheckConsoleFunctions";
|
||||
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, variant.HostingModel, publish: true);
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} {path}"); // For standalone this will need to remove space
|
||||
|
||||
var logFolderPath = _logFolderPath + "\\彡⾔";
|
||||
deploymentParameters.EnableLogging(logFolderPath);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync(path);
|
||||
|
||||
Assert.False(response.IsSuccessStatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
var contents = Helpers.ReadAllTextFromFile(Helpers.GetExpectedLogName(deploymentResult, logFolderPath), Logger);
|
||||
Assert.Contains("彡⾔", contents);
|
||||
|
||||
if (variant.HostingModel == HostingModel.InProcess)
|
||||
{
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessThreadExitStdOut(deploymentResult, "12", "(.*)彡⾔(.*)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.OutOfProcessFailedToStart(deploymentResult));
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task OnlyOneFileCreatedWithProcessStartTime(TestVariant variant)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
|
||||
deploymentParameters.EnableLogging(_logFolderPath);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
await Helpers.AssertStarts(deploymentResult, "ConsoleWrite");
|
||||
|
||||
StopServer();
|
||||
|
||||
Assert.Single(Directory.GetFiles(_logFolderPath), Helpers.GetExpectedLogName(deploymentResult, _logFolderPath));
|
||||
}
|
||||
|
||||
private static string ReadLogs(string logPath)
|
||||
{
|
||||
using (var stream = File.Open(logPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
using (var streamReader = new StreamReader(stream))
|
||||
{
|
||||
return streamReader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private static void AssertLogs(string logPath)
|
||||
{
|
||||
var logContents = ReadLogs(logPath);
|
||||
Assert.Contains("[aspnetcorev2.dll]", logContents);
|
||||
Assert.True(logContents.Contains("[aspnetcorev2_inprocess.dll]") || logContents.Contains("[aspnetcorev2_outofprocess.dll]"));
|
||||
Assert.Contains("Description: IIS ASP.NET Core Module V2. Commit:", logContents);
|
||||
Assert.Contains("Description: IIS ASP.NET Core Module V2 Request Handler. Commit:", logContents);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class MultiApplicationTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
private PublishedApplication _publishedApplication;
|
||||
private PublishedApplication _rootApplication;
|
||||
|
||||
public MultiApplicationTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RunsTwoOutOfProcessApps()
|
||||
{
|
||||
var parameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true);
|
||||
parameters.ServerConfigActionList.Add(DuplicateApplication);
|
||||
var result = await DeployAsync(parameters);
|
||||
var id1 = await result.HttpClient.GetStringAsync("/app1/ProcessId");
|
||||
var id2 = await result.HttpClient.GetStringAsync("/app2/ProcessId");
|
||||
Assert.NotEqual(id2, id1);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task FailsAndLogsWhenRunningTwoInProcessApps()
|
||||
{
|
||||
var parameters = _fixture.GetBaseDeploymentParameters(HostingModel.InProcess, publish: true);
|
||||
parameters.ServerConfigActionList.Add(DuplicateApplication);
|
||||
|
||||
var result = await DeployAsync(parameters);
|
||||
var result1 = await result.HttpClient.GetAsync("/app1/HelloWorld");
|
||||
var result2 = await result.HttpClient.GetAsync("/app2/HelloWorld");
|
||||
Assert.Equal(200, (int)result1.StatusCode);
|
||||
Assert.Equal(500, (int)result2.StatusCode);
|
||||
StopServer();
|
||||
EventLogHelpers.VerifyEventLogEvent(result, "Only one inprocess application is allowed per IIS application pool");
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData(HostingModel.OutOfProcess)]
|
||||
[InlineData(HostingModel.InProcess)]
|
||||
public async Task FailsAndLogsEventLogForMixedHostingModel(HostingModel firstApp)
|
||||
{
|
||||
var parameters = _fixture.GetBaseDeploymentParameters(firstApp, publish: true);
|
||||
parameters.ServerConfigActionList.Add(DuplicateApplication);
|
||||
var result = await DeployAsync(parameters);
|
||||
|
||||
// Modify hosting model of other app to be the opposite
|
||||
var otherApp = firstApp == HostingModel.InProcess ? HostingModel.OutOfProcess : HostingModel.InProcess;
|
||||
SetHostingModel(_publishedApplication.Path, otherApp);
|
||||
|
||||
var result1 = await result.HttpClient.GetAsync("/app1/HelloWorld");
|
||||
var result2 = await result.HttpClient.GetAsync("/app2/HelloWorld");
|
||||
Assert.Equal(200, (int)result1.StatusCode);
|
||||
Assert.Equal(500, (int)result2.StatusCode);
|
||||
StopServer();
|
||||
EventLogHelpers.VerifyEventLogEvent(result, "Mixed hosting model is not supported.");
|
||||
}
|
||||
|
||||
private void SetHostingModel(string directory, HostingModel model)
|
||||
{
|
||||
var webConfigLocation = GetWebConfigLocation(directory);
|
||||
XDocument webConfig = XDocument.Load(webConfigLocation);
|
||||
webConfig.Root
|
||||
.Descendants("system.webServer")
|
||||
.Single()
|
||||
.GetOrAdd("aspNetCore")
|
||||
.SetAttributeValue("hostingModel", model.ToString());
|
||||
webConfig.Save(webConfigLocation);
|
||||
}
|
||||
|
||||
private void DuplicateApplication(XElement config, string contentRoot)
|
||||
{
|
||||
var siteElement = config
|
||||
.RequiredElement("system.applicationHost")
|
||||
.RequiredElement("sites")
|
||||
.RequiredElement("site");
|
||||
|
||||
var application = siteElement
|
||||
.RequiredElement("application");
|
||||
|
||||
application.SetAttributeValue("path", "/app1");
|
||||
|
||||
var source = new DirectoryInfo(contentRoot);
|
||||
|
||||
var destination = new DirectoryInfo(contentRoot + "anotherApp");
|
||||
destination.Create();
|
||||
Helpers.CopyFiles(source, destination, Logger);
|
||||
|
||||
_publishedApplication = new PublishedApplication(destination.FullName, Logger);
|
||||
|
||||
var newApplication = new XElement(application);
|
||||
newApplication.SetAttributeValue("path", "/app2");
|
||||
newApplication.RequiredElement("virtualDirectory")
|
||||
.SetAttributeValue("physicalPath", destination.FullName);
|
||||
|
||||
siteElement.Add(newApplication);
|
||||
|
||||
// IIS Express requires root application to exist
|
||||
var rootApplicationDirectory = new DirectoryInfo(contentRoot + "rootApp");
|
||||
rootApplicationDirectory.Create();
|
||||
|
||||
_rootApplication = new PublishedApplication(rootApplicationDirectory.FullName, Logger);
|
||||
File.WriteAllText(GetWebConfigLocation(rootApplicationDirectory.FullName), "<configuration></configuration>");
|
||||
|
||||
var rootApplication = new XElement(application);
|
||||
rootApplication.SetAttributeValue("path", "/");
|
||||
rootApplication.RequiredElement("virtualDirectory")
|
||||
.SetAttributeValue("physicalPath", rootApplicationDirectory.FullName);
|
||||
|
||||
siteElement.Add(rootApplication);
|
||||
}
|
||||
|
||||
private static string GetWebConfigLocation(string siteRoot)
|
||||
{
|
||||
return Path.Combine(siteRoot, "web.config");
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
_rootApplication.Dispose();
|
||||
_publishedApplication.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class AspNetCorePortTests : IISFunctionalTestBase
|
||||
{
|
||||
// Port range allowed by ANCM config
|
||||
private const int _minPort = 1025;
|
||||
private const int _maxPort = 48000;
|
||||
|
||||
private static readonly Random _random = new Random();
|
||||
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public AspNetCorePortTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
public static TestMatrix TestVariants
|
||||
=> TestMatrix.ForServers(DeployerSelector.ServerType)
|
||||
.WithTfms(Tfm.NetCoreApp22)
|
||||
.WithApplicationTypes(ApplicationType.Portable)
|
||||
.WithAllAncmVersions();
|
||||
|
||||
public static IEnumerable<object[]> InvalidTestVariants
|
||||
=> from v in TestVariants.Select(v => v.Single())
|
||||
from s in new string[] { (_minPort - 1).ToString(), (_maxPort + 1).ToString(), "noninteger" }
|
||||
select new object[] { v, s };
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task EnvVarInWebConfig_Valid(TestVariant variant)
|
||||
{
|
||||
// Must publish to set env vars in web.config
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
var port = GetUnusedRandomPort();
|
||||
deploymentParameters.WebConfigBasedEnvironmentVariables["ASPNETCORE_PORT"] = port.ToString();
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var responseText = await deploymentResult.HttpClient.GetStringAsync("/ServerAddresses");
|
||||
|
||||
Assert.Equal(port, new Uri(responseText).Port);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task EnvVarInWebConfig_Empty(TestVariant variant)
|
||||
{
|
||||
// Must publish to set env vars in web.config
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
deploymentParameters.WebConfigBasedEnvironmentVariables["ASPNETCORE_PORT"] = string.Empty;
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var responseText = await deploymentResult.HttpClient.GetStringAsync("/ServerAddresses");
|
||||
|
||||
// If env var is empty, ANCM should assign a random port (same as no env var)
|
||||
Assert.InRange(new Uri(responseText).Port, _minPort, _maxPort);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(InvalidTestVariants))]
|
||||
public async Task EnvVarInWebConfig_Invalid(TestVariant variant, string port)
|
||||
{
|
||||
// Must publish to set env vars in web.config
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true);
|
||||
deploymentParameters.WebConfigBasedEnvironmentVariables["ASPNETCORE_PORT"] = port;
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/ServerAddresses");
|
||||
|
||||
Assert.Equal(HttpStatusCode.BadGateway, response.StatusCode);
|
||||
}
|
||||
|
||||
private static int GetUnusedRandomPort()
|
||||
{
|
||||
// Large number of retries to prevent test failures due to port collisions, but not infinite
|
||||
// to prevent infinite loop in case Bind() fails repeatedly for some other reason.
|
||||
const int retries = 100;
|
||||
|
||||
List<Exception> exceptions = null;
|
||||
|
||||
for (var i = 0; i < retries; i++)
|
||||
{
|
||||
var port = _random.Next(_minPort, _maxPort);
|
||||
|
||||
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
|
||||
{
|
||||
try
|
||||
{
|
||||
socket.Bind(new IPEndPoint(IPAddress.Loopback, port));
|
||||
return port;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Bind failed, most likely because port is in use. Save exception and retry.
|
||||
if (exceptions == null)
|
||||
{
|
||||
exceptions = new List<Exception>(retries);
|
||||
}
|
||||
exceptions.Add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new AggregateException($"Unable to find unused random port after {retries} retries.", exceptions);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,252 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class GlobalVersionTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public GlobalVersionTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
private const string _handlerVersion20 = "2.0.0";
|
||||
private const string _helloWorldRequest = "HelloWorld";
|
||||
private const string _helloWorldResponse = "Hello World";
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task GlobalVersion_DefaultWorks()
|
||||
{
|
||||
var deploymentParameters = GetGlobalVersionBaseDeploymentParameters();
|
||||
|
||||
deploymentParameters.HandlerSettings["handlerVersion"] = _handlerVersion20;
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync(_helloWorldRequest);
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(_helloWorldResponse, responseText);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
[RequiresNewShim]
|
||||
public async Task GlobalVersion_EnvironmentVariableWorks()
|
||||
{
|
||||
var temporaryFile = Path.GetTempFileName();
|
||||
try
|
||||
{
|
||||
var deploymentParameters = GetGlobalVersionBaseDeploymentParameters();
|
||||
CopyShimToOutput(deploymentParameters);
|
||||
deploymentParameters.PublishApplicationBeforeDeployment = true;
|
||||
deploymentParameters.EnvironmentVariables["ASPNETCORE_MODULE_OUTOFPROCESS_HANDLER"] = temporaryFile;
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
var requestHandlerPath = Path.Combine(GetANCMRequestHandlerPath(deploymentResult, _handlerVersion20), "aspnetcorev2_outofprocess.dll");
|
||||
|
||||
File.Delete(temporaryFile);
|
||||
File.Move(requestHandlerPath, temporaryFile);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync(_helloWorldRequest);
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(_helloWorldResponse, responseText);
|
||||
StopServer();
|
||||
}
|
||||
finally
|
||||
{
|
||||
File.Delete(temporaryFile);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("2.1.0")]
|
||||
[InlineData("2.1.0-preview")]
|
||||
public async Task GlobalVersion_NewVersionNumber_Fails(string version)
|
||||
{
|
||||
var deploymentParameters = GetGlobalVersionBaseDeploymentParameters();
|
||||
deploymentParameters.HandlerSettings["handlerVersion"] = version;
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync(_helloWorldRequest);
|
||||
Assert.False(response.IsSuccessStatusCode);
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
Assert.Contains("HTTP Error 500.0 - ANCM Out-Of-Process Handler Load Failure", responseString);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("2.1.0")]
|
||||
[InlineData("2.1.0-preview")]
|
||||
public async Task GlobalVersion_NewVersionNumber(string version)
|
||||
{
|
||||
var deploymentParameters = GetGlobalVersionBaseDeploymentParameters();
|
||||
CopyShimToOutput(deploymentParameters);
|
||||
deploymentParameters.HandlerSettings["handlerVersion"] = version;
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var originalANCMPath = GetANCMRequestHandlerPath(deploymentResult, _handlerVersion20);
|
||||
var newANCMPath = GetANCMRequestHandlerPath(deploymentResult, version);
|
||||
Directory.Move(originalANCMPath, newANCMPath);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync(_helloWorldRequest);
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(_helloWorldResponse, responseText);
|
||||
AssertLoadedVersion(version);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("2.1.0")]
|
||||
[InlineData("2.1.0-preview")]
|
||||
public async Task GlobalVersion_MultipleRequestHandlers_PicksHighestOne(string version)
|
||||
{
|
||||
var deploymentParameters = GetGlobalVersionBaseDeploymentParameters();
|
||||
CopyShimToOutput(deploymentParameters);
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var originalANCMPath = GetANCMRequestHandlerPath(deploymentResult, _handlerVersion20);
|
||||
|
||||
var newANCMPath = GetANCMRequestHandlerPath(deploymentResult, version);
|
||||
|
||||
CopyDirectory(originalANCMPath, newANCMPath);
|
||||
|
||||
deploymentResult.HttpClient.DefaultRequestHeaders.Add("ANCMRHPath", newANCMPath);
|
||||
var response = await deploymentResult.HttpClient.GetAsync("CheckRequestHandlerVersion");
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.Equal(_helloWorldResponse, responseText);
|
||||
AssertLoadedVersion(version);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[InlineData("2.1.0")]
|
||||
[InlineData("2.1.0-preview")]
|
||||
public async Task GlobalVersion_MultipleRequestHandlers_UpgradeWorks(string version)
|
||||
{
|
||||
var deploymentParameters = GetGlobalVersionBaseDeploymentParameters();
|
||||
CopyShimToOutput(deploymentParameters);
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var originalANCMPath = GetANCMRequestHandlerPath(deploymentResult, _handlerVersion20);
|
||||
|
||||
deploymentResult.HttpClient.DefaultRequestHeaders.Add("ANCMRHPath", originalANCMPath);
|
||||
var response = await deploymentResult.HttpClient.GetAsync("CheckRequestHandlerVersion");
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.Equal(_helloWorldResponse, responseText);
|
||||
|
||||
StopServer();
|
||||
|
||||
deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
originalANCMPath = GetANCMRequestHandlerPath(deploymentResult, _handlerVersion20);
|
||||
|
||||
var newANCMPath = GetANCMRequestHandlerPath(deploymentResult, version);
|
||||
|
||||
CopyDirectory(originalANCMPath, newANCMPath);
|
||||
|
||||
deploymentResult.HttpClient.DefaultRequestHeaders.Add("ANCMRHPath", newANCMPath);
|
||||
response = await deploymentResult.HttpClient.GetAsync("CheckRequestHandlerVersion");
|
||||
responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.Equal(_helloWorldResponse, responseText);
|
||||
AssertLoadedVersion(version);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task DoesNotCrashWhenNoVersionsAvailable()
|
||||
{
|
||||
var deploymentParameters = GetGlobalVersionBaseDeploymentParameters();
|
||||
CopyShimToOutput(deploymentParameters);
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var originalANCMPath = GetANCMRequestHandlerPath(deploymentResult, _handlerVersion20);
|
||||
Directory.Delete(originalANCMPath, true);
|
||||
var response = await deploymentResult.HttpClient.GetAsync("HelloWorld");
|
||||
|
||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||
}
|
||||
|
||||
private IISDeploymentParameters GetGlobalVersionBaseDeploymentParameters()
|
||||
{
|
||||
return _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true);
|
||||
}
|
||||
|
||||
private void CopyDirectory(string from, string to)
|
||||
{
|
||||
var toInfo = new DirectoryInfo(to);
|
||||
toInfo.Create();
|
||||
|
||||
foreach (var file in new DirectoryInfo(from).GetFiles())
|
||||
{
|
||||
file.CopyTo(Path.Combine(toInfo.FullName, file.Name));
|
||||
}
|
||||
}
|
||||
|
||||
private string GetANCMRequestHandlerPath(IISDeploymentResult deploymentResult, string version)
|
||||
{
|
||||
return Path.Combine(deploymentResult.ContentRoot,
|
||||
deploymentResult.DeploymentParameters.RuntimeArchitecture.ToString(),
|
||||
version);
|
||||
}
|
||||
|
||||
private void AssertLoadedVersion(string version)
|
||||
{
|
||||
StopServer();
|
||||
Assert.Contains(TestSink.Writes, context => context.Message.Contains(version + @"\aspnetcorev2_outofprocess.dll"));
|
||||
}
|
||||
|
||||
private static void CopyShimToOutput(IISDeploymentParameters parameters)
|
||||
{
|
||||
parameters.AddServerConfigAction(
|
||||
(config, contentRoot) => {
|
||||
var moduleNodes = config.DescendantNodesAndSelf()
|
||||
.OfType<XElement>()
|
||||
.Where(element =>
|
||||
element.Name == "add" &&
|
||||
element.Attribute("name")?.Value.StartsWith("AspNetCoreModule") == true &&
|
||||
element.Attribute("image") != null);
|
||||
|
||||
var sourceDirectory = new DirectoryInfo(Path.GetDirectoryName(moduleNodes.First().Attribute("image").Value));
|
||||
var destinationDirectory = new DirectoryInfo(Path.Combine(contentRoot, sourceDirectory.Name));
|
||||
destinationDirectory.Create();
|
||||
foreach (var element in moduleNodes)
|
||||
{
|
||||
var imageAttribute = element.Attribute("image");
|
||||
imageAttribute.Value = imageAttribute.Value.Replace(sourceDirectory.FullName, destinationDirectory.FullName);
|
||||
}
|
||||
CopyFiles(sourceDirectory, destinationDirectory);
|
||||
});
|
||||
}
|
||||
|
||||
private static void CopyFiles(DirectoryInfo source, DirectoryInfo target)
|
||||
{
|
||||
foreach (DirectoryInfo directoryInfo in source.GetDirectories())
|
||||
{
|
||||
CopyFiles(directoryInfo, target.CreateSubdirectory(directoryInfo.Name));
|
||||
}
|
||||
|
||||
foreach (FileInfo fileInfo in source.GetFiles())
|
||||
{
|
||||
var destFileName = Path.Combine(target.FullName, fileInfo.Name);
|
||||
fileInfo.CopyTo(destFileName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class HelloWorldTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public HelloWorldTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
public static TestMatrix TestVariants
|
||||
=> TestMatrix.ForServers(DeployerSelector.ServerType)
|
||||
.WithTfms(Tfm.NetCoreApp22, Tfm.Net461)
|
||||
.WithAllApplicationTypes()
|
||||
.WithAllAncmVersions();
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task HelloWorld(TestVariant variant)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant);
|
||||
deploymentParameters.ServerConfigActionList.Add(
|
||||
(element, _) => {
|
||||
element
|
||||
.RequiredElement("system.webServer")
|
||||
.RequiredElement("security")
|
||||
.RequiredElement("authentication")
|
||||
.Element("windowsAuthentication")
|
||||
?.SetAttributeValue("enabled", "false");
|
||||
});
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.Equal("Hello World", responseText);
|
||||
|
||||
response = await deploymentResult.HttpClient.GetAsync("/Path/%3F%3F?query");
|
||||
responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("/??", responseText);
|
||||
|
||||
response = await deploymentResult.HttpClient.GetAsync("/Query/%3FPath?query?");
|
||||
responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("?query?", responseText);
|
||||
|
||||
response = await deploymentResult.HttpClient.GetAsync("/BodyLimit");
|
||||
responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("null", responseText);
|
||||
|
||||
response = await deploymentResult.HttpClient.GetAsync("/Auth");
|
||||
responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.Equal("null", responseText);
|
||||
|
||||
Assert.Equal(
|
||||
$"ContentRootPath {deploymentResult.ContentRoot}" + Environment.NewLine +
|
||||
$"WebRootPath {deploymentResult.ContentRoot}\\wwwroot" + Environment.NewLine +
|
||||
$"CurrentDirectory {deploymentResult.ContentRoot}",
|
||||
await deploymentResult.HttpClient.GetStringAsync("/HostingEnvironment"));
|
||||
|
||||
var expectedDll = variant.AncmVersion == AncmVersion.AspNetCoreModule ? "aspnetcore.dll" : "aspnetcorev2.dll";
|
||||
Assert.Contains(deploymentResult.HostProcess.Modules.OfType<ProcessModule>(), m=> m.FileName.Contains(expectedDll));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
/// <summary>
|
||||
/// This type just maps collection names to available fixtures
|
||||
/// </summary>
|
||||
[CollectionDefinition(Name)]
|
||||
public class PublishedSitesCollection : ICollectionFixture<PublishedSitesFixture>, ICollectionFixture<ClientCertificateFixture>
|
||||
{
|
||||
public const string Name = nameof(PublishedSitesCollection);
|
||||
}
|
||||
|
||||
public class PublishedSitesFixture : IDisposable
|
||||
{
|
||||
public CachingApplicationPublisher InProcessTestSite { get; } = new CachingApplicationPublisher(Helpers.GetInProcessTestSitesPath());
|
||||
public CachingApplicationPublisher OutOfProcessTestSite { get; } = new CachingApplicationPublisher(Helpers.GetOutOfProcessTestSitesPath());
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
InProcessTestSite.Dispose();
|
||||
OutOfProcessTestSite.Dispose();
|
||||
}
|
||||
|
||||
public IISDeploymentParameters GetBaseDeploymentParameters(HostingModel hostingModel = HostingModel.InProcess, bool publish = false)
|
||||
{
|
||||
var publisher = hostingModel == HostingModel.InProcess ? InProcessTestSite : OutOfProcessTestSite;
|
||||
return GetBaseDeploymentParameters(publisher, hostingModel, publish);
|
||||
}
|
||||
public IISDeploymentParameters GetBaseDeploymentParameters(TestVariant variant, bool publish = false)
|
||||
{
|
||||
var publisher = variant.HostingModel == HostingModel.InProcess ? InProcessTestSite : OutOfProcessTestSite;
|
||||
return GetBaseDeploymentParameters(publisher, new DeploymentParameters(variant), publish);
|
||||
}
|
||||
|
||||
public IISDeploymentParameters GetBaseDeploymentParameters(ApplicationPublisher publisher, HostingModel hostingModel = HostingModel.InProcess, bool publish = false)
|
||||
{
|
||||
return GetBaseDeploymentParameters(
|
||||
publisher,
|
||||
new DeploymentParameters(publisher.ApplicationPath, DeployerSelector.ServerType, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64)
|
||||
{
|
||||
HostingModel = hostingModel,
|
||||
TargetFramework = "netcoreapp2.2",
|
||||
AncmVersion = AncmVersion.AspNetCoreModuleV2
|
||||
},
|
||||
publish);
|
||||
}
|
||||
|
||||
public IISDeploymentParameters GetBaseDeploymentParameters(ApplicationPublisher publisher, DeploymentParameters baseParameters, bool publish = false)
|
||||
{
|
||||
return new IISDeploymentParameters(baseParameters)
|
||||
{
|
||||
ApplicationPublisher = publisher,
|
||||
ApplicationPath = publisher.ApplicationPath,
|
||||
PublishApplicationBeforeDeployment = publish
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public sealed class RequiresNewHandlerAttribute : Attribute, ITestCondition
|
||||
{
|
||||
public bool IsMet => !DeployerSelector.IsForwardsCompatibilityTest;
|
||||
|
||||
public string SkipReason => "Test verifies new behavior in the aspnetcorev2_inprocess.dll that isn't supported in earlier versions.";
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public sealed class RequiresNewShimAttribute : Attribute, ITestCondition
|
||||
{
|
||||
public bool IsMet => !DeployerSelector.IsBackwardsCompatiblityTest;
|
||||
|
||||
public string SkipReason => "Test verifies new behavior in the aspnetcorev2.dll that isn't supported in earlier versions.";
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public abstract class ServerAbortTests: FixtureLoggedTest
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class InProc: ServerAbortTests
|
||||
{
|
||||
public InProc(IISTestSiteFixture fixture) : base(fixture) { }
|
||||
}
|
||||
|
||||
[Collection(OutOfProcessTestSiteCollection.Name)]
|
||||
public class OutOfProcess: ServerAbortTests
|
||||
{
|
||||
public OutOfProcess(OutOfProcessTestSiteFixture fixture) : base(fixture) { }
|
||||
}
|
||||
|
||||
[Collection(OutOfProcessV1TestSiteCollection.Name)]
|
||||
public class OutOfProcessV1: ServerAbortTests
|
||||
{
|
||||
public OutOfProcessV1(OutOfProcessV1TestSiteFixture fixture) : base(fixture) { }
|
||||
}
|
||||
|
||||
protected ServerAbortTests(IISTestSiteFixture fixture) : base(fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ClosesConnectionOnServerAbort()
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _fixture.Client.GetAsync("/Abort").DefaultTimeout();
|
||||
|
||||
// 502 is expected for outofproc but not for inproc
|
||||
if (_fixture.DeploymentResult.DeploymentParameters.HostingModel == HostingModel.OutOfProcess)
|
||||
{
|
||||
Assert.Equal(HttpStatusCode.BadGateway, response.StatusCode);
|
||||
// 0x80072f78 ERROR_HTTP_INVALID_SERVER_RESPONSE The server returned an invalid or unrecognized response
|
||||
Assert.Contains("0x80072f78", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.True(false, "Should not reach here");
|
||||
}
|
||||
}
|
||||
catch (HttpRequestException)
|
||||
{
|
||||
// Connection reset is expected both for outofproc and inproc
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Security.Principal;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public sealed class SkipIfNotAdminAttribute : Attribute, ITestCondition
|
||||
{
|
||||
public bool IsMet
|
||||
{
|
||||
get
|
||||
{
|
||||
var identity = WindowsIdentity.GetCurrent();
|
||||
var principal = new WindowsPrincipal(identity);
|
||||
return principal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
}
|
||||
}
|
||||
|
||||
public string SkipReason => "The current process is not running as admin.";
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public sealed class SkipInVSTSAttribute : Attribute, ITestCondition
|
||||
{
|
||||
public bool IsMet => string.IsNullOrEmpty(Environment.GetEnvironmentVariable("SYSTEM_TASKDEFINITIONSURI"));
|
||||
|
||||
public string SkipReason => "Running in VSTS";
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
||||
{
|
||||
public class AppVerifier
|
||||
{
|
||||
private static readonly TimeSpan AppVerifierCommandTimeout = TimeSpan.FromSeconds(5);
|
||||
|
||||
public static IDisposable Disable(ServerType serverType, int code)
|
||||
{
|
||||
// Set in SetupTestEnvironment.ps1
|
||||
var enabledCodes = (Environment.GetEnvironmentVariable("APPVERIFIER_ENABLED_CODES") ?? "").Split(' ');
|
||||
string processName;
|
||||
switch (serverType)
|
||||
{
|
||||
case ServerType.IISExpress:
|
||||
processName = "iisexpress.exe";
|
||||
break;
|
||||
case ServerType.IIS:
|
||||
processName = "w3wp.exe";
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(serverType), serverType, null);
|
||||
}
|
||||
|
||||
if (!enabledCodes.Contains(code.ToString()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
RunProcessAndWaitForExit("appverif.exe", $"-configure {code} -for {processName} -with ErrorReport=0", AppVerifierCommandTimeout);
|
||||
return new AppVerifierToken(processName, code.ToString());
|
||||
}
|
||||
|
||||
private static void RunProcessAndWaitForExit(string fileName, string arguments, TimeSpan timeout)
|
||||
{
|
||||
var startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = arguments,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
};
|
||||
|
||||
var process = Process.Start(startInfo);
|
||||
|
||||
if (!process.WaitForExit((int)timeout.TotalMilliseconds))
|
||||
{
|
||||
process.Kill();
|
||||
}
|
||||
|
||||
if (process.ExitCode != 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Exit code {process.ExitCode} when running {fileName} {arguments}. Stdout: {process.StandardOutput.ReadToEnd()} Stderr: {process.StandardError.ReadToEnd()}");
|
||||
}
|
||||
}
|
||||
|
||||
public class AppVerifierToken : IDisposable
|
||||
{
|
||||
private readonly string _processName;
|
||||
|
||||
private readonly string _codes;
|
||||
|
||||
public AppVerifierToken(string processName, string codes)
|
||||
{
|
||||
_processName = processName;
|
||||
_codes = codes;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
//
|
||||
RunProcessAndWaitForExit("appverif.exe", $"-configure {_codes} -for {_processName} -with ErrorReport={Environment.GetEnvironmentVariable("APPVERIFIER_LEVEL")}", AppVerifierCommandTimeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,210 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public class EventLogHelpers
|
||||
{
|
||||
public static void VerifyEventLogEvent(IISDeploymentResult deploymentResult, string expectedRegexMatchString)
|
||||
{
|
||||
Assert.True(deploymentResult.HostProcess.HasExited);
|
||||
|
||||
var entries = GetEntries(deploymentResult);
|
||||
AssertSingleEntry(expectedRegexMatchString, entries);
|
||||
}
|
||||
|
||||
public static void VerifyEventLogEvent(IISDeploymentResult deploymentResult, string expectedRegexMatchString, ILogger logger)
|
||||
{
|
||||
Assert.True(deploymentResult.HostProcess.HasExited);
|
||||
|
||||
var entries = GetEntries(deploymentResult);
|
||||
try
|
||||
{
|
||||
AssertSingleEntry(expectedRegexMatchString, entries);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
logger.LogInformation(entry.Message);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public static void VerifyEventLogEvents(IISDeploymentResult deploymentResult, params string[] expectedRegexMatchString)
|
||||
{
|
||||
Assert.True(deploymentResult.HostProcess.HasExited);
|
||||
|
||||
var entries = GetEntries(deploymentResult).ToList();
|
||||
foreach (var regexString in expectedRegexMatchString)
|
||||
{
|
||||
var matchedEntries = AssertSingleEntry(regexString, entries);
|
||||
|
||||
foreach (var matchedEntry in matchedEntries)
|
||||
{
|
||||
entries.Remove(matchedEntry);
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True(0 == entries.Count, $"Some entries were not matched by any regex {FormatEntries(entries)}");
|
||||
}
|
||||
|
||||
private static EventLogEntry[] AssertSingleEntry(string regexString, IEnumerable<EventLogEntry> entries)
|
||||
{
|
||||
var expectedRegex = new Regex(regexString, RegexOptions.Singleline);
|
||||
var matchedEntries = entries.Where(entry => expectedRegex.IsMatch(entry.Message)).ToArray();
|
||||
Assert.True(matchedEntries.Length > 0, $"No entries matched by '{regexString}'");
|
||||
Assert.True(matchedEntries.Length < 2, $"Multiple entries matched by '{regexString}': {FormatEntries(matchedEntries)}");
|
||||
return matchedEntries;
|
||||
}
|
||||
|
||||
private static string FormatEntries(IEnumerable<EventLogEntry> entries)
|
||||
{
|
||||
return string.Join(",", entries.Select(e => e.Message));
|
||||
}
|
||||
|
||||
private static IEnumerable<EventLogEntry> GetEntries(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
var eventLog = new EventLog("Application");
|
||||
|
||||
// Eventlog is already sorted based on time of event in ascending time.
|
||||
// Check results in reverse order.
|
||||
var processIdString = $"Process Id: {deploymentResult.HostProcess.Id}.";
|
||||
|
||||
// Event log messages round down to the nearest second, so subtract a second
|
||||
var processStartTime = deploymentResult.HostProcess.StartTime.AddSeconds(-1);
|
||||
for (var i = eventLog.Entries.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var eventLogEntry = eventLog.Entries[i];
|
||||
if (eventLogEntry.TimeGenerated < processStartTime)
|
||||
{
|
||||
// If event logs is older than the process start time, we didn't find a match.
|
||||
break;
|
||||
}
|
||||
|
||||
if (eventLogEntry.ReplacementStrings == null ||
|
||||
eventLogEntry.ReplacementStrings.Length < 3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// ReplacementStings == EventData collection in EventLog
|
||||
// This is unaffected if event providers are not registered correctly
|
||||
if (eventLogEntry.Source == AncmVersionToMatch(deploymentResult) &&
|
||||
processIdString == eventLogEntry.ReplacementStrings[1])
|
||||
{
|
||||
yield return eventLogEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string AncmVersionToMatch(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
return "IIS " +
|
||||
(deploymentResult.DeploymentParameters.ServerType == ServerType.IISExpress ? "Express " : "") +
|
||||
"AspNetCore Module" +
|
||||
(deploymentResult.DeploymentParameters.AncmVersion == AncmVersion.AspNetCoreModuleV2 ? " V2" : "");
|
||||
}
|
||||
|
||||
public static string Started(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
if (deploymentResult.DeploymentParameters.HostingModel == HostingModel.InProcess)
|
||||
{
|
||||
return InProcessStarted(deploymentResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
return OutOfProcessStarted(deploymentResult);
|
||||
}
|
||||
}
|
||||
|
||||
public static string InProcessStarted(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
return $"Application '{EscapedContentRoot(deploymentResult)}' started the coreclr in-process successfully";
|
||||
}
|
||||
|
||||
public static string OutOfProcessStarted(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
return $"Application '/LM/W3SVC/1/ROOT' started process '\\d+' successfully and process '\\d+' is listening on port '\\d+'.";
|
||||
}
|
||||
|
||||
public static string InProcessFailedToStart(IISDeploymentResult deploymentResult, string reason)
|
||||
{
|
||||
return $"Application '/LM/W3SVC/1/ROOT' with physical root '{EscapedContentRoot(deploymentResult)}' failed to load clr and managed application. {reason}";
|
||||
}
|
||||
|
||||
public static string InProcessFailedToStop(IISDeploymentResult deploymentResult, string reason)
|
||||
{
|
||||
return "Failed to gracefully shutdown application 'MACHINE/WEBROOT/APPHOST/.*?'.";
|
||||
}
|
||||
|
||||
public static string InProcessThreadException(IISDeploymentResult deploymentResult, string reason)
|
||||
{
|
||||
return $"Application '/LM/W3SVC/1/ROOT' with physical root '{EscapedContentRoot(deploymentResult)}' hit unexpected managed exception{reason}";
|
||||
}
|
||||
|
||||
public static string InProcessThreadExit(IISDeploymentResult deploymentResult, string code)
|
||||
{
|
||||
return $"Application '/LM/W3SVC/1/ROOT' with physical root '{EscapedContentRoot(deploymentResult)}' hit unexpected managed background thread exit, exit code = '{code}'.";
|
||||
}
|
||||
public static string InProcessThreadExitStdOut(IISDeploymentResult deploymentResult, string code, string output)
|
||||
{
|
||||
return $"Application '/LM/W3SVC/1/ROOT' with physical root '{EscapedContentRoot(deploymentResult)}' hit unexpected managed background thread exit, exit code = '{code}'. Last 4KB characters of captured stdout and stderr logs:\r\n{output}";
|
||||
}
|
||||
|
||||
public static string FailedToStartApplication(IISDeploymentResult deploymentResult, string code)
|
||||
{
|
||||
return $"Failed to start application '/LM/W3SVC/1/ROOT', ErrorCode '{code}'.";
|
||||
}
|
||||
|
||||
public static string ConfigurationLoadError(IISDeploymentResult deploymentResult, string reason)
|
||||
{
|
||||
return $"Could not load configuration. Exception message: {reason}";
|
||||
}
|
||||
|
||||
public static string OutOfProcessFailedToStart(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
return $"Application '/LM/W3SVC/1/ROOT' with physical root '{EscapedContentRoot(deploymentResult)}' failed to start process with " +
|
||||
$"commandline '(.*)' with multiple retries. " +
|
||||
$"The last try of listening port is '(.*)'. See previous warnings for details.";
|
||||
}
|
||||
|
||||
public static string InProcessHostfxrInvalid(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
return $"Hostfxr version used does not support 'hostfxr_get_native_search_directories', update the version of hostfxr to a higher version. Path to hostfxr: '(.*)'.";
|
||||
}
|
||||
|
||||
public static string InProcessFailedToFindNativeDependencies(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
return "Invoking hostfxr to find the inprocess request handler failed without finding any native dependencies. " +
|
||||
"This most likely means the app is misconfigured, please check the versions of Microsoft.NetCore.App and Microsoft.AspNetCore.App that " +
|
||||
"are targeted by the application and are installed on the machine.";
|
||||
}
|
||||
|
||||
public static string InProcessFailedToFindRequestHandler(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
return "Could not find the assembly '(.*)' referenced for the in-process application. Please confirm the Microsoft.AspNetCore.Server.IIS package is referenced in your application.";
|
||||
}
|
||||
|
||||
private static string EscapedContentRoot(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
var contentRoot = deploymentResult.ContentRoot;
|
||||
if (!contentRoot.EndsWith('\\'))
|
||||
{
|
||||
contentRoot += '\\';
|
||||
}
|
||||
return Regex.Escape(contentRoot);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
||||
{
|
||||
public class FunctionalTestsBase : LoggedTest
|
||||
{
|
||||
private const string DebugEnvironmentVariable = "ASPNETCORE_MODULE_DEBUG";
|
||||
|
||||
public FunctionalTestsBase(ITestOutputHelper output = null) : base(output)
|
||||
{
|
||||
}
|
||||
|
||||
protected IISDeployerBase _deployer;
|
||||
|
||||
protected ApplicationDeployer CreateDeployer(IISDeploymentParameters parameters)
|
||||
{
|
||||
if (parameters.ServerType == ServerType.IISExpress &&
|
||||
!parameters.EnvironmentVariables.ContainsKey(DebugEnvironmentVariable))
|
||||
{
|
||||
parameters.EnvironmentVariables[DebugEnvironmentVariable] = "console";
|
||||
}
|
||||
|
||||
return IISApplicationDeployerFactory.Create(parameters, LoggerFactory);
|
||||
}
|
||||
|
||||
protected virtual async Task<IISDeploymentResult> DeployAsync(IISDeploymentParameters parameters)
|
||||
{
|
||||
_deployer = (IISDeployerBase)CreateDeployer(parameters);
|
||||
return (IISDeploymentResult)await _deployer.DeployAsync();
|
||||
}
|
||||
|
||||
protected virtual async Task<IISDeploymentResult> StartAsync(IISDeploymentParameters parameters)
|
||||
{
|
||||
var result = await DeployAsync(parameters);
|
||||
await result.AssertStarts();
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
StopServer(false);
|
||||
}
|
||||
|
||||
public void StopServer(bool gracefulShutdown = true)
|
||||
{
|
||||
_deployer?.Dispose(gracefulShutdown);
|
||||
_deployer = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,241 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public static class Helpers
|
||||
{
|
||||
private static readonly TimeSpan RetryRequestDelay = TimeSpan.FromMilliseconds(100);
|
||||
private static readonly int RetryRequestCount = 10;
|
||||
|
||||
public static string GetTestWebSitePath(string name)
|
||||
{
|
||||
return Path.Combine(TestPathUtilities.GetSolutionRootDirectory("IISIntegration"),"test", "WebSites", name);
|
||||
}
|
||||
|
||||
public static string GetInProcessTestSitesPath()
|
||||
{
|
||||
return DeployerSelector.IsForwardsCompatibilityTest ? GetTestWebSitePath("InProcessForwardsCompatWebSite") : GetTestWebSitePath("InProcessWebSite");
|
||||
}
|
||||
|
||||
public static string GetOutOfProcessTestSitesPath() => GetTestWebSitePath("OutOfProcessWebSite");
|
||||
|
||||
public static async Task AssertStarts(this IISDeploymentResult deploymentResult, string path = "/HelloWorld")
|
||||
{
|
||||
var response = await deploymentResult.HttpClient.GetAsync(path);
|
||||
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.Equal("Hello World", responseText);
|
||||
}
|
||||
|
||||
public static async Task StressLoad(HttpClient httpClient, string path, Action<HttpResponseMessage> action)
|
||||
{
|
||||
async Task RunRequests()
|
||||
{
|
||||
var connection = new HttpClient() { BaseAddress = httpClient.BaseAddress };
|
||||
|
||||
for (int j = 0; j < 10; j++)
|
||||
{
|
||||
var response = await connection.GetAsync(path);
|
||||
action(response);
|
||||
}
|
||||
}
|
||||
|
||||
List<Task> tasks = new List<Task>();
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
tasks.Add(Task.Run(RunRequests));
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
public static string GetFrebFolder(string folder, IISDeploymentResult result)
|
||||
{
|
||||
if (result.DeploymentParameters.ServerType == ServerType.IISExpress)
|
||||
{
|
||||
return Path.Combine(folder, result.DeploymentParameters.SiteName);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Path.Combine(folder, "W3SVC1");
|
||||
}
|
||||
}
|
||||
|
||||
public static void CopyFiles(DirectoryInfo source, DirectoryInfo target, ILogger logger)
|
||||
{
|
||||
foreach (DirectoryInfo directoryInfo in source.GetDirectories())
|
||||
{
|
||||
if (directoryInfo.FullName != target.FullName)
|
||||
{
|
||||
CopyFiles(directoryInfo, target.CreateSubdirectory(directoryInfo.Name), logger);
|
||||
}
|
||||
}
|
||||
logger?.LogDebug($"Processing {target.FullName}");
|
||||
foreach (FileInfo fileInfo in source.GetFiles())
|
||||
{
|
||||
logger?.LogDebug($" Copying {fileInfo.Name}");
|
||||
var destFileName = Path.Combine(target.FullName, fileInfo.Name);
|
||||
fileInfo.CopyTo(destFileName);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ModifyWebConfig(this DeploymentResult deploymentResult, Action<XElement> action)
|
||||
{
|
||||
var webConfigPath = Path.Combine(deploymentResult.ContentRoot, "web.config");
|
||||
var document = XDocument.Load(webConfigPath);
|
||||
action(document.Root);
|
||||
document.Save(webConfigPath);
|
||||
}
|
||||
|
||||
public static Task<HttpResponseMessage> RetryRequestAsync(this HttpClient client, string uri, Func<HttpResponseMessage, bool> predicate)
|
||||
{
|
||||
return RetryRequestAsync(client, uri, message => Task.FromResult(predicate(message)));
|
||||
}
|
||||
|
||||
public static async Task<HttpResponseMessage> RetryRequestAsync(this HttpClient client, string uri, Func<HttpResponseMessage, Task<bool>> predicate)
|
||||
{
|
||||
HttpResponseMessage response = await client.GetAsync(uri);
|
||||
|
||||
for (var i = 0; i < RetryRequestCount && !await predicate(response); i++)
|
||||
{
|
||||
// Keep retrying until app_offline is present.
|
||||
response = await client.GetAsync(uri);
|
||||
await Task.Delay(RetryRequestDelay);
|
||||
}
|
||||
|
||||
if (!await predicate(response))
|
||||
{
|
||||
throw new InvalidOperationException($"Didn't get response that satisfies predicate after {RetryRequestCount} retries");
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public static async Task Retry(Func<Task> func, int attempts, int msDelay)
|
||||
{
|
||||
var exceptions = new List<Exception>();
|
||||
|
||||
for (var attempt = 0; attempt < attempts; attempt++)
|
||||
{
|
||||
try
|
||||
{
|
||||
await func();
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exceptions.Add(e);
|
||||
}
|
||||
await Task.Delay(msDelay);
|
||||
}
|
||||
|
||||
throw new AggregateException(exceptions);
|
||||
}
|
||||
|
||||
public static void AssertWorkerProcessStop(this IISDeploymentResult deploymentResult, int? timeout = null)
|
||||
{
|
||||
var hostProcess = deploymentResult.HostProcess;
|
||||
Assert.True(hostProcess.WaitForExit(timeout ?? (int)TimeoutExtensions.DefaultTimeoutValue.TotalMilliseconds));
|
||||
|
||||
if (deploymentResult.DeploymentParameters.ServerType == ServerType.IISExpress)
|
||||
{
|
||||
Assert.Equal(0, hostProcess.ExitCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async Task AssertRecycledAsync(this IISDeploymentResult deploymentResult, Func<Task> verificationAction = null)
|
||||
{
|
||||
if (deploymentResult.DeploymentParameters.HostingModel != HostingModel.InProcess)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
deploymentResult.AssertWorkerProcessStop();
|
||||
if (deploymentResult.DeploymentParameters.ServerType == ServerType.IIS)
|
||||
{
|
||||
verificationAction = verificationAction ?? (() => deploymentResult.AssertStarts());
|
||||
await verificationAction();
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> ToTheoryData<T>(this Dictionary<string, T> dictionary)
|
||||
{
|
||||
return dictionary.Keys.Select(k => new[] { k });
|
||||
}
|
||||
|
||||
public static string GetExpectedLogName(IISDeploymentResult deploymentResult, string logFolderPath)
|
||||
{
|
||||
var startTime = deploymentResult.HostProcess.StartTime.ToUniversalTime();
|
||||
|
||||
if (deploymentResult.DeploymentParameters.HostingModel == HostingModel.InProcess)
|
||||
{
|
||||
return Path.Combine(logFolderPath, $"std_{startTime.Year}{startTime.Month:D2}" +
|
||||
$"{startTime.Day:D2}{startTime.Hour:D2}" +
|
||||
$"{startTime.Minute:D2}{startTime.Second:D2}_" +
|
||||
$"{deploymentResult.HostProcess.Id}.log");
|
||||
}
|
||||
else
|
||||
{
|
||||
return Directory.GetFiles(logFolderPath).Single();
|
||||
}
|
||||
}
|
||||
|
||||
public static void ModifyFrameworkVersionInRuntimeConfig(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
var path = Path.Combine(deploymentResult.ContentRoot, "InProcessWebSite.runtimeconfig.json");
|
||||
dynamic depsFileContent = JsonConvert.DeserializeObject(File.ReadAllText(path));
|
||||
depsFileContent["runtimeOptions"]["framework"]["version"] = "2.9.9";
|
||||
var output = JsonConvert.SerializeObject(depsFileContent);
|
||||
File.WriteAllText(path, output);
|
||||
}
|
||||
|
||||
public static void AllowNoLogs(this IISDeploymentResult deploymentResult)
|
||||
{
|
||||
File.AppendAllText(
|
||||
Path.Combine(deploymentResult.DeploymentParameters.PublishedApplicationRootPath, "aspnetcore-debug.log"),
|
||||
"Running test allowed log file to be empty." + Environment.NewLine);
|
||||
}
|
||||
|
||||
public static string ReadAllTextFromFile(string filename, ILogger logger)
|
||||
{
|
||||
try
|
||||
{
|
||||
return File.ReadAllText(filename);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// check if there is a dotnet.exe, iisexpress.exe, or w3wp.exe processes still running.
|
||||
var hostingProcesses = Process.GetProcessesByName("dotnet")
|
||||
.Concat(Process.GetProcessesByName("iisexpress"))
|
||||
.Concat(Process.GetProcessesByName("w3wp"));
|
||||
|
||||
logger.LogError($"Could not read file content. Exception message {ex.Message}");
|
||||
logger.LogError("Current hosting exes running:");
|
||||
|
||||
foreach (var hostingProcess in hostingProcesses)
|
||||
{
|
||||
logger.LogError($"{hostingProcess.ProcessName} pid: {hostingProcess.Id} hasExited: {hostingProcess.HasExited.ToString()}");
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Flags]
|
||||
public enum IISCapability
|
||||
{
|
||||
None = 0,
|
||||
Websockets = 1,
|
||||
WindowsAuthentication = 2,
|
||||
PoolEnvironmentVariables = 4,
|
||||
ShutdownToken = 8,
|
||||
DynamicCompression = 16,
|
||||
ApplicationInitialization = 32,
|
||||
TracingModule = 64,
|
||||
FailedRequestTracingModule = 128,
|
||||
BasicAuthentication = 256
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[CollectionDefinition(Name)]
|
||||
public class IISCompressionSiteCollection : ICollectionFixture<IISCompressionSiteFixture>
|
||||
{
|
||||
public const string Name = nameof(IISCompressionSiteCollection);
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public class IISCompressionSiteFixture : IISTestSiteFixture
|
||||
{
|
||||
public IISCompressionSiteFixture() : base(Configure)
|
||||
{
|
||||
}
|
||||
|
||||
private static void Configure(IISDeploymentParameters deploymentParameters)
|
||||
{
|
||||
// Enable dynamic compression
|
||||
deploymentParameters.ServerConfigActionList.Add(
|
||||
(element, _) => {
|
||||
var webServerElement = element
|
||||
.RequiredElement("system.webServer");
|
||||
|
||||
webServerElement
|
||||
.GetOrAdd("urlCompression")
|
||||
.SetAttributeValue("doDynamicCompression", "true");
|
||||
|
||||
webServerElement
|
||||
.GetOrAdd("httpCompression")
|
||||
.GetOrAdd("dynamicTypes")
|
||||
.GetOrAdd("add", "mimeType", "text/*")
|
||||
.SetAttributeValue("enabled", "true");
|
||||
|
||||
});
|
||||
|
||||
deploymentParameters.EnableModule("DynamicCompressionModule", "%IIS_BIN%\\compdyn.dll");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities
|
||||
{
|
||||
public class IISFunctionalTestBase : FunctionalTestsBase
|
||||
{
|
||||
public IISFunctionalTestBase(ITestOutputHelper output = null) : base(output)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
/// <summary>
|
||||
/// This type just maps collection names to available fixtures
|
||||
/// </summary>
|
||||
[CollectionDefinition(Name)]
|
||||
public class IISTestSiteCollection : ICollectionFixture<IISTestSiteFixture>
|
||||
{
|
||||
public const string Name = nameof(IISTestSiteCollection);
|
||||
}
|
||||
|
||||
[CollectionDefinition(Name)]
|
||||
public class OutOfProcessTestSiteCollection : ICollectionFixture<OutOfProcessTestSiteFixture>
|
||||
{
|
||||
public const string Name = nameof(OutOfProcessTestSiteCollection);
|
||||
}
|
||||
|
||||
[CollectionDefinition(Name)]
|
||||
public class OutOfProcessV1TestSiteCollection : ICollectionFixture<OutOfProcessV1TestSiteFixture>
|
||||
{
|
||||
public const string Name = nameof(OutOfProcessV1TestSiteCollection);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,191 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public class OutOfProcessTestSiteFixture : IISTestSiteFixture
|
||||
{
|
||||
public OutOfProcessTestSiteFixture() : base(Configure)
|
||||
{
|
||||
}
|
||||
|
||||
private static void Configure(IISDeploymentParameters deploymentParameters)
|
||||
{
|
||||
deploymentParameters.ApplicationPath = Helpers.GetOutOfProcessTestSitesPath();
|
||||
deploymentParameters.HostingModel = HostingModel.OutOfProcess;
|
||||
}
|
||||
}
|
||||
|
||||
public class OutOfProcessV1TestSiteFixture : IISTestSiteFixture
|
||||
{
|
||||
public OutOfProcessV1TestSiteFixture() : base(Configure)
|
||||
{
|
||||
}
|
||||
|
||||
private static void Configure(IISDeploymentParameters deploymentParameters)
|
||||
{
|
||||
deploymentParameters.ApplicationPath = Helpers.GetOutOfProcessTestSitesPath();
|
||||
deploymentParameters.HostingModel = HostingModel.OutOfProcess;
|
||||
deploymentParameters.AncmVersion = AncmVersion.AspNetCoreModule;
|
||||
}
|
||||
}
|
||||
|
||||
public class IISTestSiteFixture : IDisposable
|
||||
{
|
||||
private ApplicationDeployer _deployer;
|
||||
private ILoggerFactory _loggerFactory;
|
||||
private ForwardingProvider _forwardingProvider;
|
||||
private IISDeploymentResult _deploymentResult;
|
||||
private readonly Action<IISDeploymentParameters> _configure;
|
||||
|
||||
public IISTestSiteFixture() : this(_ => { })
|
||||
{
|
||||
}
|
||||
|
||||
public IISTestSiteFixture(Action<IISDeploymentParameters> configure)
|
||||
{
|
||||
var logging = AssemblyTestLog.ForAssembly(typeof(IISTestSiteFixture).Assembly);
|
||||
_loggerFactory = logging.CreateLoggerFactory(null, nameof(IISTestSiteFixture));
|
||||
|
||||
_forwardingProvider = new ForwardingProvider();
|
||||
_loggerFactory.AddProvider(_forwardingProvider);
|
||||
|
||||
_configure = configure;
|
||||
}
|
||||
|
||||
public HttpClient Client => DeploymentResult.HttpClient;
|
||||
public IISDeploymentResult DeploymentResult
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureInitialized();
|
||||
return _deploymentResult;
|
||||
}
|
||||
}
|
||||
|
||||
public TestConnection CreateTestConnection()
|
||||
{
|
||||
return new TestConnection(Client.BaseAddress.Port);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_deployer?.Dispose();
|
||||
}
|
||||
|
||||
public void Attach(LoggedTest test)
|
||||
{
|
||||
if (_forwardingProvider.LoggerFactory != null)
|
||||
{
|
||||
throw new InvalidOperationException("Test instance is already attached to this fixture");
|
||||
}
|
||||
|
||||
_forwardingProvider.LoggerFactory = test.LoggerFactory;
|
||||
}
|
||||
|
||||
public void Detach(LoggedTest test)
|
||||
{
|
||||
if (_forwardingProvider.LoggerFactory != test.LoggerFactory)
|
||||
{
|
||||
throw new InvalidOperationException("Different test is attached to this fixture");
|
||||
}
|
||||
|
||||
_forwardingProvider.LoggerFactory = null;
|
||||
}
|
||||
|
||||
private void EnsureInitialized()
|
||||
{
|
||||
if (_deployer != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deploymentParameters = new IISDeploymentParameters(Helpers.GetInProcessTestSitesPath(),
|
||||
DeployerSelector.ServerType,
|
||||
RuntimeFlavor.CoreClr,
|
||||
RuntimeArchitecture.x64)
|
||||
{
|
||||
TargetFramework = Tfm.NetCoreApp22,
|
||||
AncmVersion = AncmVersion.AspNetCoreModuleV2,
|
||||
HostingModel = HostingModel.InProcess,
|
||||
PublishApplicationBeforeDeployment = true,
|
||||
};
|
||||
|
||||
_configure(deploymentParameters);
|
||||
|
||||
_deployer = IISApplicationDeployerFactory.Create(deploymentParameters, _loggerFactory);
|
||||
_deploymentResult = (IISDeploymentResult)_deployer.DeployAsync().Result;
|
||||
}
|
||||
|
||||
private class ForwardingProvider : ILoggerProvider
|
||||
{
|
||||
private readonly List<ForwardingLogger> _loggers = new List<ForwardingLogger>();
|
||||
|
||||
private ILoggerFactory _loggerFactory;
|
||||
|
||||
public ILoggerFactory LoggerFactory
|
||||
{
|
||||
get => _loggerFactory;
|
||||
set
|
||||
{
|
||||
|
||||
lock (_loggers)
|
||||
{
|
||||
_loggerFactory = value;
|
||||
foreach (var logger in _loggers)
|
||||
{
|
||||
logger.Logger = _loggerFactory?.CreateLogger("FIXTURE:" + logger.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
lock (_loggers)
|
||||
{
|
||||
_loggers.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public ILogger CreateLogger(string categoryName)
|
||||
{
|
||||
lock (_loggers)
|
||||
{
|
||||
var logger = new ForwardingLogger(categoryName);
|
||||
_loggers.Add(logger);
|
||||
return logger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ForwardingLogger : ILogger
|
||||
{
|
||||
public ForwardingLogger(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
|
||||
{
|
||||
Logger?.Log(logLevel, eventId, state, exception, formatter);
|
||||
}
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel) => Logger?.IsEnabled(logLevel) == true;
|
||||
|
||||
public IDisposable BeginScope<TState>(TState state) => Logger?.BeginScope(state);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities
|
||||
{
|
||||
public class LogFileTestBase : IISFunctionalTestBase
|
||||
{
|
||||
protected string _logFolderPath;
|
||||
|
||||
public LogFileTestBase(ITestOutputHelper output = null) : base(output)
|
||||
{
|
||||
_logFolderPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
}
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
if (Directory.Exists(_logFolderPath))
|
||||
{
|
||||
Directory.Delete(_logFolderPath, true);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetLogFileContent(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
return Helpers.ReadAllTextFromFile(Helpers.GetExpectedLogName(deploymentResult, _logFolderPath), Logger);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public sealed class RequiresEnvironmentVariableAttribute : Attribute, ITestCondition
|
||||
{
|
||||
private readonly string _name;
|
||||
|
||||
public RequiresEnvironmentVariableAttribute(string name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
public bool IsMet => !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(_name));
|
||||
|
||||
public string SkipReason => $"Environment variable {_name} is required to run this test.";
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public sealed class SkipIfDebugAttribute : Attribute, ITestCondition
|
||||
{
|
||||
public bool IsMet =>
|
||||
#if DEBUG
|
||||
false;
|
||||
#else
|
||||
true;
|
||||
#endif
|
||||
|
||||
public string SkipReason => "Test cannot be run in Debug mode.";
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class WindowsAuthTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public WindowsAuthTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
public static TestMatrix TestVariants
|
||||
=> TestMatrix.ForServers(DeployerSelector.ServerType)
|
||||
.WithTfms(Tfm.NetCoreApp22, Tfm.Net461)
|
||||
.WithApplicationTypes(ApplicationType.Portable)
|
||||
.WithAllAncmVersions()
|
||||
.WithAllHostingModels();
|
||||
|
||||
[ConditionalTheory]
|
||||
[RequiresIIS(IISCapability.WindowsAuthentication)]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task WindowsAuthTest(TestVariant variant)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant);
|
||||
deploymentParameters.SetAnonymousAuth(enabled: false);
|
||||
deploymentParameters.SetWindowsAuth();
|
||||
|
||||
// The default in hosting sets windows auth to true.
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var client = deploymentResult.CreateClient(new HttpClientHandler { UseDefaultCredentials = true });
|
||||
var response = await client.GetAsync("/Auth");
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.StartsWith("Windows:", responseText);
|
||||
Assert.Contains(Environment.UserName, responseText);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.2</TargetFrameworks>
|
||||
<IsTestProject>false</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IntegrationTesting" Version="$(MicrosoftAspNetCoreServerIntegrationTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
|
||||
<PackageReference Include="System.Diagnostics.EventLog" Version="$(SystemDiagnosticsEventLogPackageVersion)" />
|
||||
<PackageReference Include="System.Net.WebSockets.WebSocketProtocol" Version="$(SystemNetWebSocketsWebSocketProtocolPackageVersion)" />
|
||||
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
||||
{
|
||||
public class DisposableList<T> : List<T>, IDisposable where T : IDisposable
|
||||
{
|
||||
public DisposableList() : base() { }
|
||||
|
||||
public DisposableList(IEnumerable<T> collection) : base(collection) { }
|
||||
|
||||
public DisposableList(int capacity) : base(capacity) { }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var item in this)
|
||||
{
|
||||
item?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,252 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for TestConnection
|
||||
/// </summary>
|
||||
public class TestConnection : IDisposable
|
||||
{
|
||||
private static readonly TimeSpan Timeout = TimeSpan.FromMinutes(1);
|
||||
|
||||
private readonly bool _ownsSocket;
|
||||
private readonly Socket _socket;
|
||||
private readonly NetworkStream _stream;
|
||||
|
||||
public TestConnection(int port)
|
||||
: this(port, AddressFamily.InterNetwork)
|
||||
{
|
||||
}
|
||||
|
||||
public TestConnection(int port, AddressFamily addressFamily)
|
||||
: this(CreateConnectedLoopbackSocket(port, addressFamily), ownsSocket: true)
|
||||
{
|
||||
}
|
||||
|
||||
public TestConnection(Socket socket)
|
||||
: this(socket, ownsSocket: false)
|
||||
{
|
||||
}
|
||||
|
||||
private TestConnection(Socket socket, bool ownsSocket)
|
||||
{
|
||||
_ownsSocket = ownsSocket;
|
||||
_socket = socket;
|
||||
_stream = new NetworkStream(_socket, ownsSocket: false);
|
||||
}
|
||||
|
||||
public Socket Socket => _socket;
|
||||
public Stream Stream => _stream;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_stream.Dispose();
|
||||
|
||||
if (_ownsSocket)
|
||||
{
|
||||
_socket.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Send(params string[] lines)
|
||||
{
|
||||
var bytes = Encoding.ASCII.GetBytes(string.Join("\r\n", lines));
|
||||
|
||||
for (var index = 0; index < bytes.Length; index++)
|
||||
{
|
||||
await _stream.WriteAsync(bytes, index, 1).ConfigureAwait(false);
|
||||
await _stream.FlushAsync().ConfigureAwait(false);
|
||||
// Re-add delay to help find socket input consumption bugs more consistently
|
||||
//await Task.Delay(TimeSpan.FromMilliseconds(5));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<int> ReadCharAsync()
|
||||
{
|
||||
var bytes = new byte[1];
|
||||
return (await _stream.ReadAsync(bytes, 0, 1) == 1) ? bytes[0] : -1;
|
||||
}
|
||||
|
||||
public async Task<string> ReadLineAsync()
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
var current = await ReadCharAsync();
|
||||
while (current != '\r')
|
||||
{
|
||||
builder.Append((char)current);
|
||||
current = await ReadCharAsync();
|
||||
}
|
||||
|
||||
// Consume \n
|
||||
await ReadCharAsync();
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public async Task<Memory<byte>> ReceiveChunk()
|
||||
{
|
||||
var length = int.Parse(await ReadLineAsync(), System.Globalization.NumberStyles.HexNumber);
|
||||
|
||||
var bytes = await Receive(length);
|
||||
|
||||
await ReadLineAsync();
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public async Task ReceiveChunk(string expected)
|
||||
{
|
||||
Assert.Equal(expected, Encoding.ASCII.GetString((await ReceiveChunk()).Span));
|
||||
}
|
||||
|
||||
public async Task Receive(params string[] lines)
|
||||
{
|
||||
var expected = string.Join("\r\n", lines);
|
||||
var actual = await Receive(expected.Length);
|
||||
|
||||
Assert.Equal(expected, Encoding.ASCII.GetString(actual.Span));
|
||||
}
|
||||
|
||||
private async Task<Memory<byte>> Receive(int length)
|
||||
{
|
||||
var actual = new byte[length];
|
||||
int offset = 0;
|
||||
try
|
||||
{
|
||||
while (offset < length)
|
||||
{
|
||||
var task = _stream.ReadAsync(actual, offset, actual.Length - offset);
|
||||
if (!Debugger.IsAttached)
|
||||
{
|
||||
task = task.TimeoutAfter(Timeout);
|
||||
}
|
||||
|
||||
var count = await task.ConfigureAwait(false);
|
||||
if (count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
offset += count;
|
||||
}
|
||||
}
|
||||
catch (TimeoutException ex) when (offset != 0)
|
||||
{
|
||||
throw new TimeoutException(
|
||||
$"Did not receive a complete response within {Timeout}.{Environment.NewLine}{Environment.NewLine}" +
|
||||
$"Expected:{Environment.NewLine}{length} bytes of data{Environment.NewLine}{Environment.NewLine}" +
|
||||
$"Actual:{Environment.NewLine}{Encoding.ASCII.GetString(actual, 0, offset)}{Environment.NewLine}",
|
||||
ex);
|
||||
}
|
||||
|
||||
return actual.AsMemory(0, offset);
|
||||
}
|
||||
|
||||
public async Task ReceiveStartsWith(string prefix, int maxLineLength = 1024)
|
||||
{
|
||||
var actual = new byte[maxLineLength];
|
||||
var offset = 0;
|
||||
|
||||
while (offset < maxLineLength)
|
||||
{
|
||||
// Read one char at a time so we don't read past the end of the line.
|
||||
var task = _stream.ReadAsync(actual, offset, 1);
|
||||
if (!Debugger.IsAttached)
|
||||
{
|
||||
Assert.True(task.Wait(4000), "timeout");
|
||||
}
|
||||
var count = await task.ConfigureAwait(false);
|
||||
if (count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Assert.True(count == 1);
|
||||
offset++;
|
||||
|
||||
if (actual[offset - 1] == '\n')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var actualLine = Encoding.ASCII.GetString(actual, 0, offset);
|
||||
Assert.StartsWith(prefix, actualLine);
|
||||
}
|
||||
|
||||
public async Task<string[]> ReceiveHeaders(params string[] lines)
|
||||
{
|
||||
List<string> headers = new List<string>();
|
||||
string line;
|
||||
do
|
||||
{
|
||||
line = await ReadLineAsync();
|
||||
headers.Add(line);
|
||||
} while (line != "");
|
||||
|
||||
foreach (var s in lines)
|
||||
{
|
||||
Assert.Contains(s, headers);
|
||||
}
|
||||
|
||||
return headers.ToArray();
|
||||
}
|
||||
|
||||
public Task WaitForConnectionClose()
|
||||
{
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
var eventArgs = new SocketAsyncEventArgs();
|
||||
eventArgs.SetBuffer(new byte[128], 0, 128);
|
||||
eventArgs.Completed += ReceiveAsyncCompleted;
|
||||
eventArgs.UserToken = tcs;
|
||||
|
||||
if (!_socket.ReceiveAsync(eventArgs))
|
||||
{
|
||||
ReceiveAsyncCompleted(this, eventArgs);
|
||||
}
|
||||
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
private void ReceiveAsyncCompleted(object sender, SocketAsyncEventArgs e)
|
||||
{
|
||||
var tcs = (TaskCompletionSource<object>)e.UserToken;
|
||||
if (e.BytesTransferred == 0)
|
||||
{
|
||||
tcs.SetResult(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
tcs.SetException(new IOException(
|
||||
$"Expected connection close, received data instead: \"{Encoding.ASCII.GetString(e.Buffer, 0, e.BytesTransferred)}\""));
|
||||
}
|
||||
}
|
||||
|
||||
public static Socket CreateConnectedLoopbackSocket(int port, AddressFamily addressFamily)
|
||||
{
|
||||
if (addressFamily != AddressFamily.InterNetwork && addressFamily != AddressFamily.InterNetworkV6)
|
||||
{
|
||||
throw new ArgumentException($"TestConnection does not support address family of type {addressFamily}", nameof(addressFamily));
|
||||
}
|
||||
|
||||
var socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||
var address = addressFamily == AddressFamily.InterNetworkV6
|
||||
? IPAddress.IPv6Loopback
|
||||
: IPAddress.Loopback;
|
||||
socket.Connect(new IPEndPoint(address, port));
|
||||
return socket;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
||||
{
|
||||
|
||||
public static class TimeoutExtensions
|
||||
{
|
||||
public static TimeSpan DefaultTimeoutValue = TimeSpan.FromSeconds(300);
|
||||
|
||||
public static Task DefaultTimeout(this Task task, [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = -1)
|
||||
{
|
||||
return task.TimeoutAfter(DefaultTimeoutValue, filePath, lineNumber);
|
||||
}
|
||||
|
||||
public static Task<T> DefaultTimeout<T>(this Task<T> task, [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = -1)
|
||||
{
|
||||
return task.TimeoutAfter(DefaultTimeoutValue, filePath, lineNumber);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,196 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{1eac8125-1765-4e2d-8cbe-56dc98a1c8c1}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings" />
|
||||
<ImportGroup Label="Shared" />
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Helpers.h" />
|
||||
<ClInclude Include="fakeclasses.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ConfigUtilityTests.cpp" />
|
||||
<ClCompile Include="FileOutputManagerTests.cpp" />
|
||||
<ClCompile Include="GlobalVersionTests.cpp" />
|
||||
<ClCompile Include="Helpers.cpp" />
|
||||
<ClCompile Include="hostfxr_utility_tests.cpp" />
|
||||
<ClCompile Include="inprocess_application_tests.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="PipeOutputManagerTests.cpp" />
|
||||
<ClCompile Include="utility_tests.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\AspNetCoreModuleV2\AspNetCore\AspNetCore.vcxproj">
|
||||
<Project>{ec82302f-d2f0-4727-99d1-eabc0dd9dc3b}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\src\AspNetCoreModuleV2\CommonLib\CommonLib.vcxproj">
|
||||
<Project>{55494e58-e061-4c4c-a0a8-837008e72f85}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\src\AspNetCoreModuleV2\IISLib\IISLib.vcxproj">
|
||||
<Project>{09d9d1d6-2951-4e14-bc35-76a23cf9391a}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\src\AspNetCoreModuleV2\RequestHandlerLib\RequestHandlerLib.vcxproj">
|
||||
<Project>{1533e271-f61b-441b-8b74-59fb61df0552}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\gtest\gtest.vcxproj">
|
||||
<Project>{cac1267b-8778-4257-aac6-caf481723b01}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\InProcessRequestHandler.vcxproj">
|
||||
<Project>{d57ea297-6dc2-4bc0-8c91-334863327863}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemDefinitionGroup />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\RequestHandlerLib;..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest\googletest\googletest\include;..\gtest\googletest\googlemock\include;...\..\src\AspNetCoreModuleV2\AspNetCore\Inc;..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/D "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING" </AdditionalOptions>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalLibraryDirectories>..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\$(Configuration)\;</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;stdafx.obj;version.lib;inprocessoptions.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>
|
||||
</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\RequestHandlerLib;..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest\googletest\googletest\include;..\gtest\googletest\googlemock\include;...\..\src\AspNetCoreModuleV2\AspNetCore\Inc;..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/D "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING" </AdditionalOptions>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalLibraryDirectories>..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\x64\$(Configuration)\;</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;stdafx.obj;version.lib;inprocessoptions.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>
|
||||
</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\RequestHandlerLib;..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest\googletest\googletest\include;..\gtest\googletest\googlemock\include;...\..\src\AspNetCoreModuleV2\AspNetCore\Inc;..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/D "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING" </AdditionalOptions>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<AdditionalLibraryDirectories>..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\$(Configuration)\;</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;stdafx.obj;version.lib;inprocessoptions.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>
|
||||
</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PreprocessorDefinitions>X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\RequestHandlerLib;..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest\googletest\googletest\include;..\gtest\googletest\googlemock\include;...\..\src\AspNetCoreModuleV2\AspNetCore\Inc;..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/D "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING" </AdditionalOptions>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalOptions>/NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions)</AdditionalOptions>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<AdditionalLibraryDirectories>..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\x64\$(Configuration)\;</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;stdafx.obj;version.lib;inprocessoptions.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>
|
||||
</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project=".\NativeTests.targets" />
|
||||
</Project>
|
|
@ -1,123 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "gmock/gmock.h"
|
||||
using ::testing::_;
|
||||
using ::testing::NiceMock;
|
||||
|
||||
namespace ConfigUtilityTests
|
||||
{
|
||||
using ::testing::Test;
|
||||
|
||||
class ConfigUtilityTest : public Test
|
||||
{
|
||||
protected:
|
||||
void TestHandlerVersion(std::wstring key, std::wstring value, std::wstring expected, HRESULT(*func)(IAppHostElement*, STRU&))
|
||||
{
|
||||
IAppHostElement* retElement = NULL;
|
||||
|
||||
STRU handlerVersion;
|
||||
|
||||
// NiceMock removes warnings about "uninteresting calls",
|
||||
auto element = std::make_unique<NiceMock<MockElement>>();
|
||||
auto innerElement = std::make_unique<NiceMock<MockElement>>();
|
||||
auto collection = std::make_unique<NiceMock<MockCollection>>();
|
||||
auto nameElement = std::make_unique<NiceMock<MockElement>>();
|
||||
auto mockProperty = std::make_unique<NiceMock<MockProperty>>();
|
||||
|
||||
ON_CALL(*element, GetElementByName(_, _))
|
||||
.WillByDefault(DoAll(testing::SetArgPointee<1>(innerElement.get()), testing::Return(S_OK)));
|
||||
ON_CALL(*innerElement, get_Collection(_))
|
||||
.WillByDefault(testing::DoAll(testing::SetArgPointee<0>(collection.get()), testing::Return(S_OK)));
|
||||
ON_CALL(*collection, get_Count(_))
|
||||
.WillByDefault(DoAll(testing::SetArgPointee<0>(1), testing::Return(S_OK)));
|
||||
ON_CALL(*collection, get_Item(_, _))
|
||||
.WillByDefault(DoAll(testing::SetArgPointee<1>(nameElement.get()), testing::Return(S_OK)));
|
||||
ON_CALL(*nameElement, GetPropertyByName(_, _))
|
||||
.WillByDefault(DoAll(testing::SetArgPointee<1>(mockProperty.get()), testing::Return(S_OK)));
|
||||
EXPECT_CALL(*mockProperty, get_StringValue(_))
|
||||
.WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(key.c_str())), testing::Return(S_OK)))
|
||||
.WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(value.c_str())), testing::Return(S_OK)));
|
||||
|
||||
HRESULT hr = func(element.get(), handlerVersion);
|
||||
|
||||
EXPECT_EQ(hr, S_OK);
|
||||
EXPECT_STREQ(handlerVersion.QueryStr(), expected.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(ConfigUtilityTest, CheckHandlerVersionKeysAndValues)
|
||||
{
|
||||
auto func = ConfigUtility::FindHandlerVersion;
|
||||
TestHandlerVersion(L"handlerVersion", L"value", L"value", func);
|
||||
TestHandlerVersion(L"handlerversion", L"value", L"value", func);
|
||||
TestHandlerVersion(L"HandlerversioN", L"value", L"value", func);
|
||||
TestHandlerVersion(L"randomvalue", L"value", L"", func);
|
||||
TestHandlerVersion(L"", L"value", L"", func);
|
||||
TestHandlerVersion(L"", L"", L"", func);
|
||||
}
|
||||
|
||||
TEST_F(ConfigUtilityTest, CheckDebugLogFile)
|
||||
{
|
||||
auto func = ConfigUtility::FindDebugFile;
|
||||
|
||||
TestHandlerVersion(L"debugFile", L"value", L"value", func);
|
||||
TestHandlerVersion(L"debugFILE", L"value", L"value", func);
|
||||
}
|
||||
|
||||
TEST_F(ConfigUtilityTest, CheckDebugLevel)
|
||||
{
|
||||
auto func = ConfigUtility::FindDebugLevel;
|
||||
|
||||
TestHandlerVersion(L"debugLevel", L"value", L"value", func);
|
||||
TestHandlerVersion(L"debugLEVEL", L"value", L"value", func);
|
||||
}
|
||||
|
||||
TEST(ConfigUtilityTestSingle, MultipleElements)
|
||||
{
|
||||
IAppHostElement* retElement = NULL;
|
||||
STRU handlerVersion;
|
||||
|
||||
auto element = std::make_unique<NiceMock<MockElement>>();
|
||||
auto innerElement = std::make_unique<NiceMock<MockElement>>();
|
||||
auto collection = std::make_unique<NiceMock<MockCollection>>();
|
||||
auto nameElement = std::make_unique<NiceMock<MockElement>>();
|
||||
auto mockProperty = std::make_unique<NiceMock<MockProperty>>();
|
||||
|
||||
ON_CALL(*element, GetElementByName(_, _))
|
||||
.WillByDefault(DoAll(testing::SetArgPointee<1>(innerElement.get()), testing::Return(S_OK)));
|
||||
ON_CALL(*innerElement, get_Collection(_))
|
||||
.WillByDefault(testing::DoAll(testing::SetArgPointee<0>(collection.get()), testing::Return(S_OK)));
|
||||
ON_CALL(*collection, get_Count(_))
|
||||
.WillByDefault(DoAll(testing::SetArgPointee<0>(2), testing::Return(S_OK)));
|
||||
ON_CALL(*collection, get_Item(_, _))
|
||||
.WillByDefault(DoAll(testing::SetArgPointee<1>(nameElement.get()), testing::Return(S_OK)));
|
||||
ON_CALL(*nameElement, GetPropertyByName(_, _))
|
||||
.WillByDefault(DoAll(testing::SetArgPointee<1>(mockProperty.get()), testing::Return(S_OK)));
|
||||
EXPECT_CALL(*mockProperty, get_StringValue(_))
|
||||
.WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(L"key")), testing::Return(S_OK)))
|
||||
.WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(L"value")), testing::Return(S_OK)))
|
||||
.WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(L"handlerVersion")), testing::Return(S_OK)))
|
||||
.WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(L"value2")), testing::Return(S_OK)));
|
||||
|
||||
HRESULT hr = ConfigUtility::FindHandlerVersion(element.get(), handlerVersion);
|
||||
|
||||
EXPECT_EQ(hr, S_OK);
|
||||
EXPECT_STREQ(handlerVersion.QueryStr(), L"value2");
|
||||
}
|
||||
|
||||
TEST(ConfigUtilityTestSingle, IgnoresFailedGetElement)
|
||||
{
|
||||
STRU handlerVersion;
|
||||
|
||||
auto element = std::make_unique<NiceMock<MockElement>>();
|
||||
ON_CALL(*element, GetElementByName(_, _))
|
||||
.WillByDefault(DoAll(testing::SetArgPointee<1>(nullptr), testing::Return(HRESULT_FROM_WIN32( ERROR_INVALID_INDEX ))));
|
||||
|
||||
HRESULT hr = ConfigUtility::FindHandlerVersion(element.get(), handlerVersion);
|
||||
|
||||
EXPECT_EQ(hr, S_OK);
|
||||
EXPECT_STREQ(handlerVersion.QueryStr(), L"");
|
||||
}
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "FileOutputManager.h"
|
||||
|
||||
class FileManagerWrapper
|
||||
{
|
||||
public:
|
||||
FileOutputManager* manager;
|
||||
FileManagerWrapper(FileOutputManager* m)
|
||||
: manager(m)
|
||||
{
|
||||
manager->Start();
|
||||
}
|
||||
|
||||
~FileManagerWrapper()
|
||||
{
|
||||
delete manager;
|
||||
}
|
||||
};
|
||||
|
||||
namespace FileOutManagerStartupTests
|
||||
{
|
||||
using ::testing::Test;
|
||||
class FileOutputManagerTest : public Test
|
||||
{
|
||||
protected:
|
||||
void
|
||||
Test(std::wstring fileNamePrefix, FILE* out)
|
||||
{
|
||||
PCWSTR expected = L"test";
|
||||
|
||||
auto tempDirectory = TempDirectory();
|
||||
FileOutputManager* pManager = new FileOutputManager(fileNamePrefix, tempDirectory.path());
|
||||
|
||||
{
|
||||
FileManagerWrapper wrapper(pManager);
|
||||
|
||||
wprintf(expected, out);
|
||||
}
|
||||
|
||||
for (auto & p : std::filesystem::directory_iterator(tempDirectory.path()))
|
||||
{
|
||||
std::wstring filename(p.path().filename());
|
||||
ASSERT_EQ(filename.substr(0, fileNamePrefix.size()), fileNamePrefix);
|
||||
|
||||
std::wstring content = Helpers::ReadFileContent(std::wstring(p.path()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(FileOutputManagerTest, WriteToFileCheckContentsWritten)
|
||||
{
|
||||
Test(L"", stdout);
|
||||
Test(L"log", stdout);
|
||||
}
|
||||
|
||||
TEST_F(FileOutputManagerTest, WriteToFileCheckContentsWrittenErr)
|
||||
{
|
||||
Test(L"", stderr);
|
||||
Test(L"log", stderr);
|
||||
}
|
||||
}
|
||||
|
||||
namespace FileOutManagerOutputTests
|
||||
{
|
||||
TEST(FileOutManagerOutputTest, StdOut)
|
||||
{
|
||||
PCWSTR expected = L"test";
|
||||
|
||||
auto tempDirectory = TempDirectory();
|
||||
|
||||
FileOutputManager* pManager = new FileOutputManager(L"", tempDirectory.path());
|
||||
{
|
||||
FileManagerWrapper wrapper(pManager);
|
||||
|
||||
fwprintf(stdout, expected);
|
||||
pManager->Stop();
|
||||
|
||||
auto output = pManager->GetStdOutContent();
|
||||
ASSERT_FALSE(output.empty());
|
||||
|
||||
ASSERT_STREQ(output.c_str(), expected);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FileOutManagerOutputTest, StdErr)
|
||||
{
|
||||
PCWSTR expected = L"test";
|
||||
|
||||
auto tempDirectory = TempDirectory();
|
||||
|
||||
FileOutputManager* pManager = new FileOutputManager(L"", tempDirectory.path().c_str());
|
||||
{
|
||||
FileManagerWrapper wrapper(pManager);
|
||||
|
||||
fwprintf(stderr, expected);
|
||||
pManager->Stop();
|
||||
|
||||
auto output = pManager->GetStdOutContent();
|
||||
ASSERT_FALSE(output.empty());
|
||||
|
||||
ASSERT_STREQ(output.c_str(), expected);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FileOutManagerOutputTest, CapAt30KB)
|
||||
{
|
||||
PCWSTR expected = L"hello world";
|
||||
|
||||
auto tempDirectory = TempDirectory();
|
||||
|
||||
FileOutputManager* pManager = new FileOutputManager(L"", tempDirectory.path());
|
||||
{
|
||||
FileManagerWrapper wrapper(pManager);
|
||||
|
||||
for (int i = 0; i < 3000; i++)
|
||||
{
|
||||
wprintf(expected);
|
||||
}
|
||||
pManager->Stop();
|
||||
auto output = pManager->GetStdOutContent();
|
||||
ASSERT_FALSE(output.empty());
|
||||
|
||||
ASSERT_EQ(output.size(), 30000);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FileOutManagerOutputTest, StartStopRestoresCorrectly)
|
||||
{
|
||||
PCWSTR expected = L"test";
|
||||
|
||||
auto tempDirectory = TempDirectory();
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
FileOutputManager* pManager = new FileOutputManager(L"", tempDirectory.path());
|
||||
{
|
||||
FileManagerWrapper wrapper(pManager);
|
||||
|
||||
wprintf(expected);
|
||||
pManager->Stop();
|
||||
auto output = pManager->GetStdOutContent();
|
||||
ASSERT_FALSE(output.empty());
|
||||
|
||||
ASSERT_STREQ(output.c_str(), expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
namespace GlobalVersionTests
|
||||
{
|
||||
using ::testing::Test;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
class GlobalVersionTest : public Test
|
||||
{
|
||||
protected:
|
||||
void
|
||||
RemoveFileNamePath(PCWSTR dllPath, PCWSTR expected)
|
||||
{
|
||||
std::wstring res = GlobalVersionUtility::RemoveFileNameFromFolderPath(dllPath);
|
||||
EXPECT_STREQ(res.c_str(), expected);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(GlobalVersionTest, RemovesPathCorrectly)
|
||||
{
|
||||
RemoveFileNamePath(L"test\\log.txt", L"test");
|
||||
RemoveFileNamePath(L"test\\log", L"test");
|
||||
RemoveFileNamePath(L"C:\\Program Files\\IIS\\aspnetcorev2.dll", L"C:\\Program Files\\IIS");
|
||||
RemoveFileNamePath(L"test\\log.txt", L"test");
|
||||
}
|
||||
|
||||
TEST(GetRequestHandlerVersions, GetFolders)
|
||||
{
|
||||
auto tempPath = TempDirectory();
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / L"2.0.0"));
|
||||
|
||||
auto res = GlobalVersionUtility::GetRequestHandlerVersions(tempPath.path().c_str());
|
||||
EXPECT_EQ(res.size(), 1);
|
||||
EXPECT_EQ(res.at(0), fx_ver_t(2, 0, 0, std::wstring()));
|
||||
}
|
||||
|
||||
TEST(GetRequestHandlerVersions, GetFolderPreview)
|
||||
{
|
||||
auto tempPath = TempDirectory();
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / L"2.0.0-preview"));
|
||||
|
||||
auto res = GlobalVersionUtility::GetRequestHandlerVersions(tempPath.path().c_str());
|
||||
EXPECT_EQ(res.size(), 1);
|
||||
EXPECT_EQ(res.at(0), fx_ver_t(2, 0, 0, std::wstring(L"-preview")));
|
||||
}
|
||||
|
||||
TEST(GetRequestHandlerVersions, GetFolderManyVersions)
|
||||
{
|
||||
auto tempPath = TempDirectory();
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / + L"2.0.0"));
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / + L"1.9.0"));
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / + L"2.1.0"));
|
||||
|
||||
auto res = GlobalVersionUtility::GetRequestHandlerVersions(tempPath.path().c_str());
|
||||
EXPECT_EQ(res.size(), 3);
|
||||
EXPECT_TRUE(std::find(res.begin(), res.end(), fx_ver_t(1, 9, 0, std::wstring())) != std::end(res));
|
||||
EXPECT_TRUE(std::find(res.begin(), res.end(), fx_ver_t(2, 0, 0, std::wstring())) != std::end(res));
|
||||
EXPECT_TRUE(std::find(res.begin(), res.end(), fx_ver_t(2, 1, 0, std::wstring())) != std::end(res));
|
||||
}
|
||||
|
||||
TEST(FindHighestGlobalVersion, HighestVersionWithSingleFolder)
|
||||
{
|
||||
auto tempPath = TempDirectory();
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0"));
|
||||
|
||||
auto res = GlobalVersionUtility::FindHighestGlobalVersion(tempPath.path().c_str());
|
||||
|
||||
EXPECT_STREQ(res.c_str(), L"2.0.0");
|
||||
}
|
||||
|
||||
TEST(FindHighestGlobalVersion, HighestVersionWithMultipleVersions)
|
||||
{
|
||||
auto tempPath = TempDirectory();
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0"));
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0"));
|
||||
|
||||
auto res = GlobalVersionUtility::FindHighestGlobalVersion(tempPath.path().c_str());
|
||||
|
||||
EXPECT_STREQ(res.c_str(), L"2.1.0");
|
||||
}
|
||||
|
||||
TEST(FindHighestGlobalVersion, HighestVersionWithMultipleVersionsPreview)
|
||||
{
|
||||
auto tempPath = TempDirectory();
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0"));
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0"));
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.2.0-preview"));
|
||||
|
||||
auto res = GlobalVersionUtility::FindHighestGlobalVersion(tempPath.path().c_str());
|
||||
|
||||
EXPECT_STREQ(res.c_str(), L"2.2.0-preview");
|
||||
}
|
||||
|
||||
TEST(FindHighestGlobalVersion, HighestVersionWithMultipleVersionNoPreview)
|
||||
{
|
||||
auto tempPath = TempDirectory();
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0"));
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0-preview"));
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0"));
|
||||
|
||||
auto res = GlobalVersionUtility::FindHighestGlobalVersion(tempPath.path().c_str());
|
||||
|
||||
EXPECT_STREQ(res.c_str(), L"2.1.0");
|
||||
}
|
||||
|
||||
TEST(GetGlobalRequestHandlerPath, FindHighestVersionNoHandlerName)
|
||||
{
|
||||
auto tempPath = TempDirectory();
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0"));
|
||||
auto result = GlobalVersionUtility::GetGlobalRequestHandlerPath(tempPath.path().c_str(), L"", L"aspnetcorev2_outofprocess.dll");
|
||||
|
||||
EXPECT_STREQ(result.c_str(), (tempPath.path() / L"2.0.0\\aspnetcorev2_outofprocess.dll").c_str());
|
||||
}
|
||||
|
||||
TEST(GetGlobalRequestHandlerPath, FindHighestVersionPreviewWins)
|
||||
{
|
||||
auto tempPath = TempDirectory();
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0"));
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0-preview"));
|
||||
|
||||
auto result = GlobalVersionUtility::GetGlobalRequestHandlerPath(tempPath.path().c_str(), L"", L"aspnetcorev2_outofprocess.dll");
|
||||
|
||||
EXPECT_STREQ(result.c_str(), (tempPath.path() / L"2.1.0-preview\\aspnetcorev2_outofprocess.dll").c_str());
|
||||
}
|
||||
|
||||
TEST(GetGlobalRequestHandlerPath, FindHighestVersionSpecificVersion)
|
||||
{
|
||||
auto tempPath = TempDirectory();
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0"));
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0-preview"));
|
||||
|
||||
auto result = GlobalVersionUtility::GetGlobalRequestHandlerPath(tempPath.path().c_str(), L"2.0.0", L"aspnetcorev2_outofprocess.dll");
|
||||
|
||||
EXPECT_STREQ(result.c_str(), (tempPath.path() / L"2.0.0\\aspnetcorev2_outofprocess.dll").c_str());
|
||||
}
|
||||
|
||||
TEST(GetGlobalRequestHandlerPath, FindHighestVersionSpecificPreview)
|
||||
{
|
||||
auto tempPath = TempDirectory();
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0"));
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0-preview"));
|
||||
EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.2.0"));
|
||||
|
||||
|
||||
auto result = GlobalVersionUtility::GetGlobalRequestHandlerPath(tempPath.path().c_str(), L"2.1.0-preview", L"aspnetcorev2_outofprocess.dll");
|
||||
|
||||
EXPECT_STREQ(result.c_str(), (tempPath.path() / L"2.1.0-preview\\aspnetcorev2_outofprocess.dll").c_str());
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
std::wstring
|
||||
Helpers::ReadFileContent(std::wstring file)
|
||||
{
|
||||
std::wcout << file << std::endl;
|
||||
|
||||
std::fstream t(file);
|
||||
std::stringstream buffer;
|
||||
buffer << t.rdbuf();
|
||||
|
||||
int nChars = MultiByteToWideChar(CP_ACP, 0, buffer.str().c_str(), -1, NULL, 0);
|
||||
|
||||
std::wstring retVal(nChars, '\0');
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, 0, buffer.str().c_str(), -1, retVal.data(), nChars);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
TempDirectory::TempDirectory()
|
||||
{
|
||||
UUID uuid;
|
||||
UuidCreate(&uuid);
|
||||
RPC_CSTR szUuid = NULL;
|
||||
if (UuidToStringA(&uuid, &szUuid) == RPC_S_OK)
|
||||
{
|
||||
m_path = std::filesystem::temp_directory_path() / reinterpret_cast<PCHAR>(szUuid);
|
||||
RpcStringFreeA(&szUuid);
|
||||
return;
|
||||
}
|
||||
throw std::exception("Cannot create temp directory");
|
||||
}
|
||||
|
||||
TempDirectory::~TempDirectory()
|
||||
{
|
||||
std::filesystem::remove_all(m_path);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
#pragma once
|
||||
class Helpers
|
||||
{
|
||||
public:
|
||||
static
|
||||
std::wstring
|
||||
ReadFileContent(std::wstring file);
|
||||
};
|
||||
|
||||
class TempDirectory
|
||||
{
|
||||
public:
|
||||
|
||||
TempDirectory();
|
||||
|
||||
~TempDirectory();
|
||||
|
||||
std::filesystem::path path() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
private:
|
||||
std::filesystem::path m_path;
|
||||
};
|
|
@ -1,8 +0,0 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<VsTestConsole>$(VCIDEInstallDir)..\CommonExtensions\Microsoft\TestWindow\vstest.console.exe</VsTestConsole>
|
||||
</PropertyGroup>
|
||||
<Target Name="Test" DependsOnTargets="Build">
|
||||
<Exec Command=""$(TargetPath)"" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,162 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "PipeOutputManager.h"
|
||||
|
||||
class FileManagerWrapper
|
||||
{
|
||||
public:
|
||||
PipeOutputManager * manager;
|
||||
FileManagerWrapper(PipeOutputManager* m)
|
||||
: manager(m)
|
||||
{
|
||||
manager->Start();
|
||||
}
|
||||
|
||||
~FileManagerWrapper()
|
||||
{
|
||||
delete manager;
|
||||
}
|
||||
};
|
||||
|
||||
namespace PipeOutputManagerTests
|
||||
{
|
||||
TEST(PipeManagerOutputTest, StdOut)
|
||||
{
|
||||
PCWSTR expected = L"test";
|
||||
|
||||
PipeOutputManager* pManager = new PipeOutputManager(true);
|
||||
|
||||
pManager->Start();
|
||||
fwprintf(stdout, expected);
|
||||
pManager->Stop();
|
||||
|
||||
auto output = pManager->GetStdOutContent();
|
||||
ASSERT_STREQ(output.c_str(), expected);
|
||||
delete pManager;
|
||||
}
|
||||
|
||||
TEST(PipeManagerOutputTest, StdOutMultiToWide)
|
||||
{
|
||||
PipeOutputManager* pManager = new PipeOutputManager(true);
|
||||
|
||||
pManager->Start();
|
||||
fprintf(stdout, "test");
|
||||
pManager->Stop();
|
||||
|
||||
auto output = pManager->GetStdOutContent();
|
||||
ASSERT_STREQ(output.c_str(), L"test");
|
||||
delete pManager;
|
||||
}
|
||||
|
||||
TEST(PipeManagerOutputTest, StdErr)
|
||||
{
|
||||
PCWSTR expected = L"test";
|
||||
|
||||
PipeOutputManager* pManager = new PipeOutputManager();
|
||||
|
||||
pManager->Start();
|
||||
fwprintf(stderr, expected);
|
||||
pManager->Stop();
|
||||
|
||||
auto output = pManager->GetStdOutContent();
|
||||
ASSERT_STREQ(output.c_str(), expected);
|
||||
delete pManager;
|
||||
}
|
||||
|
||||
TEST(PipeManagerOutputTest, CheckMaxPipeSize)
|
||||
{
|
||||
std::wstring test;
|
||||
for (int i = 0; i < 3000; i++)
|
||||
{
|
||||
test.append(L"hello world");
|
||||
}
|
||||
|
||||
PipeOutputManager* pManager = new PipeOutputManager();
|
||||
|
||||
pManager->Start();
|
||||
wprintf(test.c_str());
|
||||
pManager->Stop();
|
||||
|
||||
auto output = pManager->GetStdOutContent();
|
||||
ASSERT_EQ(output.size(), (DWORD)30000);
|
||||
delete pManager;
|
||||
}
|
||||
|
||||
TEST(PipeManagerOutputTest, SetInvalidHandlesForErrAndOut)
|
||||
{
|
||||
auto m_fdPreviousStdOut = _dup(_fileno(stdout));
|
||||
auto m_fdPreviousStdErr = _dup(_fileno(stderr));
|
||||
|
||||
SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE);
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE);
|
||||
|
||||
PCWSTR expected = L"test";
|
||||
|
||||
PipeOutputManager* pManager = new PipeOutputManager();
|
||||
pManager->Start();
|
||||
|
||||
_dup2(m_fdPreviousStdOut, _fileno(stdout));
|
||||
_dup2(m_fdPreviousStdErr, _fileno(stderr));
|
||||
|
||||
// Test will fail if we didn't redirect stdout back to a file descriptor.
|
||||
// This is because gtest relies on console output to know if a test succeeded or failed.
|
||||
// If the output still points to a file/pipe, the test (and all other tests after it) will fail.
|
||||
delete pManager;
|
||||
}
|
||||
|
||||
TEST(PipeManagerOutputTest, CreateDeleteMultipleTimesStdOutWorks)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
auto stdoutBefore = _fileno(stdout);
|
||||
auto stderrBefore = _fileno(stderr);
|
||||
PCWSTR expected = L"test";
|
||||
|
||||
PipeOutputManager* pManager = new PipeOutputManager();
|
||||
|
||||
pManager->Start();
|
||||
fwprintf(stdout, expected);
|
||||
|
||||
pManager->Stop();
|
||||
|
||||
auto output = pManager->GetStdOutContent();
|
||||
ASSERT_STREQ(output.c_str(), expected);
|
||||
ASSERT_EQ(stdoutBefore, _fileno(stdout));
|
||||
ASSERT_EQ(stderrBefore, _fileno(stderr));
|
||||
delete pManager;
|
||||
}
|
||||
// When this returns, we get an AV from gtest.
|
||||
}
|
||||
|
||||
TEST(PipeManagerOutputTest, CreateDeleteKeepOriginalStdErr)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
auto stdoutBefore = _fileno(stdout);
|
||||
auto stderrBefore = _fileno(stderr);
|
||||
auto stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
auto stderrHandle = GetStdHandle(STD_ERROR_HANDLE);
|
||||
PCWSTR expected = L"test";
|
||||
|
||||
PipeOutputManager* pManager = new PipeOutputManager();
|
||||
|
||||
pManager->Start();
|
||||
fwprintf(stderr, expected);
|
||||
pManager->Stop();
|
||||
|
||||
auto output = pManager->GetStdOutContent();
|
||||
ASSERT_STREQ(output.c_str(), expected);
|
||||
ASSERT_EQ(stdoutBefore, _fileno(stdout));
|
||||
|
||||
ASSERT_EQ(stderrBefore, _fileno(stderr));
|
||||
|
||||
delete pManager;
|
||||
}
|
||||
|
||||
wprintf(L"Hello!");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
TEST(CaughtExceptionHResult, ReturnsOutOfMemoryForBadAlloc)
|
||||
{
|
||||
HRESULT hr;
|
||||
try
|
||||
{
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
hr = CaughtExceptionHResult();
|
||||
}
|
||||
|
||||
EXPECT_EQ(E_OUTOFMEMORY, hr);
|
||||
}
|
||||
|
||||
TEST(CaughtExceptionHResult, ReturnsValueForSystemError)
|
||||
{
|
||||
HRESULT hr;
|
||||
try
|
||||
{
|
||||
throw std::system_error(E_INVALIDARG, std::system_category());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
hr = CaughtExceptionHResult();
|
||||
}
|
||||
|
||||
EXPECT_EQ(E_INVALIDARG, hr);
|
||||
}
|
||||
|
||||
TEST(CaughtExceptionHResult, ReturnsUhandledExceptionForOtherExceptions)
|
||||
{
|
||||
HRESULT hr;
|
||||
try
|
||||
{
|
||||
throw E_INVALIDARG;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
hr = CaughtExceptionHResult();
|
||||
}
|
||||
|
||||
EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION), hr);
|
||||
}
|
|
@ -1,190 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "InProcessOptions.h"
|
||||
|
||||
class MockProperty : public IAppHostProperty
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD2_WITH_CALLTYPE(__stdcall, QueryInterface, HRESULT(REFIID riid, void ** ppvObject));
|
||||
MOCK_METHOD0_WITH_CALLTYPE(__stdcall, AddRef, ULONG());
|
||||
MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Release, ULONG());
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Name, HRESULT(BSTR* pbstrValue));
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Value, HRESULT(VARIANT * pVariant));
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, put_Value, HRESULT(VARIANT value));
|
||||
MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Clear, HRESULT());
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_StringValue, HRESULT(BSTR* pbstrValue));
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Exception, HRESULT(IAppHostPropertyException ** ppException));
|
||||
MOCK_METHOD2_WITH_CALLTYPE(__stdcall, GetMetadata, HRESULT(BSTR bstrMetadataType, VARIANT * pValue));
|
||||
MOCK_METHOD2_WITH_CALLTYPE(__stdcall, SetMetadata, HRESULT(BSTR bstrMetadataType, VARIANT value));
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Schema, HRESULT(IAppHostPropertySchema ** ppSchema));
|
||||
};
|
||||
|
||||
class MockCollection : public IAppHostElementCollection
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD2_WITH_CALLTYPE(__stdcall, QueryInterface, HRESULT(REFIID riid, void ** ppvObject));
|
||||
MOCK_METHOD0_WITH_CALLTYPE(__stdcall, AddRef, ULONG());
|
||||
MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Release, ULONG());
|
||||
MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Clear, HRESULT());
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Schema, HRESULT(IAppHostCollectionSchema** pSchema));
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Count, HRESULT(DWORD * dwordElem));
|
||||
MOCK_METHOD2_WITH_CALLTYPE(__stdcall, get_Item, HRESULT(VARIANT cIndex, IAppHostElement ** ppElement));
|
||||
MOCK_METHOD2_WITH_CALLTYPE(__stdcall, AddElement, HRESULT(IAppHostElement * pElement, INT cPosition));
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, DeleteElement, HRESULT(VARIANT cIndex));
|
||||
MOCK_METHOD2_WITH_CALLTYPE(__stdcall, CreateNewElement, HRESULT(BSTR bstrElementName, IAppHostElement** ppElement));
|
||||
};
|
||||
|
||||
class MockElement : public IAppHostElement
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD2_WITH_CALLTYPE(__stdcall, QueryInterface, HRESULT(REFIID riid, void ** ppvObject));
|
||||
MOCK_METHOD0_WITH_CALLTYPE(__stdcall, AddRef, ULONG());
|
||||
MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Release, ULONG());
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Name, HRESULT(BSTR * pbstrName));
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Collection, HRESULT(IAppHostElementCollection ** ppCollection));
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Properties, HRESULT(IAppHostPropertyCollection ** ppProperties));
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_ChildElements, HRESULT(IAppHostChildElementCollection ** ppElements));
|
||||
MOCK_METHOD2_WITH_CALLTYPE(__stdcall, GetMetadata, HRESULT(BSTR bstrMetadataType, VARIANT * pValue));
|
||||
MOCK_METHOD2_WITH_CALLTYPE(__stdcall, SetMetadata, HRESULT(BSTR bstrMetadataType, VARIANT value));
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Schema, HRESULT(IAppHostElementSchema** pSchema));
|
||||
MOCK_METHOD2_WITH_CALLTYPE(__stdcall, GetElementByName, HRESULT(BSTR bstrSubName, IAppHostElement ** ppElement));
|
||||
MOCK_METHOD2_WITH_CALLTYPE(__stdcall, GetPropertyByName, HRESULT(BSTR bstrSubName, IAppHostProperty ** ppProperty));
|
||||
MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Clear, HRESULT());
|
||||
MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Methods, HRESULT(IAppHostMethodCollection ** ppMethods));
|
||||
};
|
||||
|
||||
class MockHttpServer : public IHttpServer
|
||||
{
|
||||
// Inherited via IHttpServer
|
||||
virtual BOOL IsCommandLineLaunch(VOID) const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual PCWSTR GetAppPoolName(VOID) const override
|
||||
{
|
||||
return PCWSTR();
|
||||
}
|
||||
virtual HRESULT AssociateWithThreadPool(HANDLE hHandle, LPOVERLAPPED_COMPLETION_ROUTINE completionRoutine) override
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
virtual VOID IncrementThreadCount(VOID) override
|
||||
{
|
||||
return VOID();
|
||||
}
|
||||
virtual VOID DecrementThreadCount(VOID) override
|
||||
{
|
||||
return VOID();
|
||||
}
|
||||
virtual VOID ReportUnhealthy(PCWSTR pszReasonString, HRESULT hrReason) override
|
||||
{
|
||||
return VOID();
|
||||
}
|
||||
virtual VOID RecycleProcess(PCWSTR pszReason) override
|
||||
{
|
||||
return VOID();
|
||||
}
|
||||
virtual IAppHostAdminManager * GetAdminManager(VOID) const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
virtual HRESULT GetFileInfo(PCWSTR pszPhysicalPath, HANDLE hUserToken, PSID pSid, PCWSTR pszChangeNotificationPath, HANDLE hChangeNotificationToken, BOOL fCache, IHttpFileInfo ** ppFileInfo, IHttpTraceContext * pHttpTraceContext = NULL) override
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
virtual HRESULT FlushKernelCache(PCWSTR pszUrl) override
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
virtual HRESULT DoCacheOperation(CACHE_OPERATION cacheOperation, IHttpCacheKey * pCacheKey, IHttpCacheSpecificData ** ppCacheSpecificData, IHttpTraceContext * pHttpTraceContext = NULL) override
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
virtual GLOBAL_NOTIFICATION_STATUS NotifyCustomNotification(ICustomNotificationProvider * pCustomOutput) override
|
||||
{
|
||||
return GLOBAL_NOTIFICATION_STATUS();
|
||||
}
|
||||
virtual IHttpPerfCounterInfo * GetPerfCounterInfo(VOID) override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
virtual VOID RecycleApplication(PCWSTR pszAppConfigPath) override
|
||||
{
|
||||
return VOID();
|
||||
}
|
||||
virtual VOID NotifyConfigurationChange(PCWSTR pszPath) override
|
||||
{
|
||||
return VOID();
|
||||
}
|
||||
virtual VOID NotifyFileChange(PCWSTR pszFileName) override
|
||||
{
|
||||
return VOID();
|
||||
}
|
||||
virtual IDispensedHttpModuleContextContainer * DispenseContainer(VOID) override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
virtual HRESULT AddFragmentToCache(HTTP_DATA_CHUNK * pDataChunk, PCWSTR pszFragmentName) override
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
virtual HRESULT ReadFragmentFromCache(PCWSTR pszFragmentName, BYTE * pvBuffer, DWORD cbSize, DWORD * pcbCopied) override
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
virtual HRESULT RemoveFragmentFromCache(PCWSTR pszFragmentName) override
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
virtual HRESULT GetWorkerProcessSettings(IWpfSettings ** ppWorkerProcessSettings) override
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
virtual HRESULT GetProtocolManagerCustomInterface(PCWSTR pProtocolManagerDll, PCWSTR pProtocolManagerDllInitFunction, DWORD dwCustomInterfaceId, PVOID * ppCustomInterface) override
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
virtual BOOL SatisfiesPrecondition(PCWSTR pszPrecondition, BOOL * pfUnknownPrecondition = NULL) const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual IHttpTraceContext * GetTraceContext(VOID) const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
virtual HRESULT RegisterFileChangeMonitor(PCWSTR pszPath, HANDLE hToken, IHttpFileMonitor ** ppFileMonitor) override
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
virtual HRESULT GetExtendedInterface(HTTP_SERVER_INTERFACE_VERSION version, PVOID * ppInterface) override
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class MockHttpApplication: public IHttpApplication
|
||||
{
|
||||
public:
|
||||
MOCK_CONST_METHOD0(GetApplicationPhysicalPath, PCWSTR ());
|
||||
MOCK_CONST_METHOD0(GetApplicationId, PCWSTR ());
|
||||
MOCK_CONST_METHOD0(GetAppConfigPath, PCWSTR ());
|
||||
MOCK_METHOD0(GetModuleContextContainer, IHttpModuleContextContainer* ());
|
||||
};
|
||||
|
||||
class MockInProcessOptions : public InProcessOptions
|
||||
{
|
||||
public:
|
||||
static
|
||||
MockInProcessOptions*
|
||||
CreateConfig()
|
||||
{
|
||||
return new MockInProcessOptions;
|
||||
}
|
||||
};
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "hostfxr_utility.h"
|
||||
#include "Environment.h"
|
||||
|
||||
TEST(ParseHostFxrArguments, BasicHostFxrArguments)
|
||||
{
|
||||
std::vector<std::wstring> bstrArray;
|
||||
|
||||
HOSTFXR_UTILITY::AppendArguments(
|
||||
L"exec \"test.dll\"", // args
|
||||
L"invalid", // physical path to application
|
||||
bstrArray); // args array.
|
||||
|
||||
EXPECT_EQ(2, bstrArray.size());
|
||||
ASSERT_STREQ(L"exec", bstrArray[0].c_str());
|
||||
ASSERT_STREQ(L"test.dll", bstrArray[1].c_str());
|
||||
}
|
||||
|
||||
TEST(ParseHostFxrArguments, NoExecProvided)
|
||||
{
|
||||
std::vector<std::wstring> bstrArray;
|
||||
|
||||
HOSTFXR_UTILITY::AppendArguments(
|
||||
L"test.dll", // args
|
||||
L"ignored", // physical path to application
|
||||
bstrArray); // args array.
|
||||
|
||||
EXPECT_EQ(1, bstrArray.size());
|
||||
ASSERT_STREQ(L"test.dll", bstrArray[0].c_str());
|
||||
}
|
||||
|
||||
TEST(ParseHostFxrArguments, ConvertDllToAbsolutePath)
|
||||
{
|
||||
std::vector<std::wstring> bstrArray;
|
||||
// we need to use existing dll so let's use ntdll that we know exists everywhere
|
||||
auto system32 = Environment::ExpandEnvironmentVariables(L"%WINDIR%\\System32");
|
||||
HOSTFXR_UTILITY::AppendArguments(
|
||||
L"exec \"ntdll.dll\"", // args
|
||||
system32, // physical path to application
|
||||
bstrArray, // args array.
|
||||
true); // expandDllPaths
|
||||
|
||||
EXPECT_EQ(2, bstrArray.size());
|
||||
ASSERT_STREQ(L"exec", bstrArray[0].c_str());
|
||||
ASSERT_STREQ((system32 + L"\\ntdll.dll").c_str(), bstrArray[1].c_str());
|
||||
}
|
||||
|
||||
TEST(ParseHostFxrArguments, ProvideNoArgs_InvalidArgs)
|
||||
{
|
||||
std::vector<std::wstring> bstrArray;
|
||||
std::filesystem::path struHostFxrDllLocation;
|
||||
std::filesystem::path struExeLocation;
|
||||
|
||||
EXPECT_THROW(HOSTFXR_UTILITY::GetHostFxrParameters(
|
||||
L"dotnet", // processPath
|
||||
L"some\\path", // application physical path, ignored.
|
||||
L"", //arguments
|
||||
struHostFxrDllLocation,
|
||||
struExeLocation,
|
||||
bstrArray), // args array.
|
||||
InvalidOperationException);
|
||||
}
|
||||
|
||||
TEST(GetAbsolutePathToDotnetFromProgramFiles, BackupWorks)
|
||||
{
|
||||
STRU struAbsolutePathToDotnet;
|
||||
BOOL fDotnetInProgramFiles;
|
||||
BOOL is64Bit;
|
||||
BOOL fIsWow64 = FALSE;
|
||||
SYSTEM_INFO systemInfo;
|
||||
IsWow64Process(GetCurrentProcess(), &fIsWow64);
|
||||
if (fIsWow64)
|
||||
{
|
||||
is64Bit = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetNativeSystemInfo(&systemInfo);
|
||||
is64Bit = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
|
||||
}
|
||||
|
||||
if (is64Bit)
|
||||
{
|
||||
fDotnetInProgramFiles = std::filesystem::is_regular_file(L"C:/Program Files/dotnet/dotnet.exe");
|
||||
}
|
||||
else
|
||||
{
|
||||
fDotnetInProgramFiles = std::filesystem::is_regular_file(L"C:/Program Files (x86)/dotnet/dotnet.exe");
|
||||
}
|
||||
|
||||
auto dotnetPath = HOSTFXR_UTILITY::GetAbsolutePathToDotnetFromProgramFiles();
|
||||
if (fDotnetInProgramFiles)
|
||||
{
|
||||
EXPECT_TRUE(dotnetPath.has_value());
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_FALSE(dotnetPath.has_value());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(GetHostFxrArguments, InvalidParams)
|
||||
{
|
||||
std::vector<std::wstring> bstrArray;
|
||||
std::filesystem::path struHostFxrDllLocation;
|
||||
std::filesystem::path struExeLocation;
|
||||
|
||||
EXPECT_THROW(HOSTFXR_UTILITY::GetHostFxrParameters(
|
||||
L"bogus", // processPath
|
||||
L"", // application physical path, ignored.
|
||||
L"ignored", //arguments
|
||||
struHostFxrDllLocation,
|
||||
struExeLocation,
|
||||
bstrArray), // args array.
|
||||
InvalidOperationException);
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <array>
|
||||
#include "inprocessapplication.h"
|
||||
#include "fakeclasses.h"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::NiceMock;
|
||||
|
||||
// Externals defined in inprocess
|
||||
BOOL g_fProcessDetach;
|
||||
HANDLE g_hEventLog;
|
||||
|
||||
namespace InprocessTests
|
||||
{
|
||||
TEST(InProcessTest, NoNullRefForExePath)
|
||||
{
|
||||
MockHttpServer server;
|
||||
NiceMock<MockHttpApplication> application;
|
||||
|
||||
ON_CALL(application, GetApplicationPhysicalPath())
|
||||
.WillByDefault(testing::Return(L"Some path"));
|
||||
|
||||
ON_CALL(application, GetAppConfigPath())
|
||||
.WillByDefault(testing::Return(L""));
|
||||
|
||||
ON_CALL(application, GetApplicationId())
|
||||
.WillByDefault(testing::Return(L""));
|
||||
|
||||
auto requestHandlerConfig = std::unique_ptr<InProcessOptions>(MockInProcessOptions::CreateConfig());
|
||||
|
||||
std::wstring exePath(L"hello");
|
||||
|
||||
std::array<APPLICATION_PARAMETER, 1> parameters{
|
||||
{"InProcessExeLocation", exePath.data()}
|
||||
};
|
||||
|
||||
IN_PROCESS_APPLICATION *app = new IN_PROCESS_APPLICATION(server, application, std::move(requestHandlerConfig), parameters.data(), 1);
|
||||
|
||||
ASSERT_STREQ(app->QueryExeLocation().c_str(), L"hello");
|
||||
}
|
||||
|
||||
TEST(InProcessTest, GeneratesVirtualPath)
|
||||
{
|
||||
MockHttpServer server;
|
||||
NiceMock<MockHttpApplication> application;
|
||||
|
||||
ON_CALL(application, GetApplicationPhysicalPath())
|
||||
.WillByDefault(testing::Return(L"Some path"));
|
||||
|
||||
ON_CALL(application, GetAppConfigPath())
|
||||
.WillByDefault(testing::Return(L"SECTION1/SECTION2/SECTION3/SECTION4/SECTION5"));
|
||||
|
||||
ON_CALL(application, GetApplicationId())
|
||||
.WillByDefault(testing::Return(L""));
|
||||
|
||||
auto requestHandlerConfig = std::unique_ptr<InProcessOptions>(MockInProcessOptions::CreateConfig());
|
||||
IN_PROCESS_APPLICATION *app = new IN_PROCESS_APPLICATION(server, application, std::move(requestHandlerConfig), nullptr, 0);
|
||||
|
||||
ASSERT_STREQ(app->QueryApplicationVirtualPath().c_str(), L"/SECTION5");
|
||||
}
|
||||
|
||||
TEST(InProcessTest, GeneratesVirtualPathForDefaultApp)
|
||||
{
|
||||
MockHttpServer server;
|
||||
NiceMock<MockHttpApplication> application;
|
||||
|
||||
ON_CALL(application, GetApplicationPhysicalPath())
|
||||
.WillByDefault(testing::Return(L"Some path"));
|
||||
|
||||
ON_CALL(application, GetAppConfigPath())
|
||||
.WillByDefault(testing::Return(L"SECTION1/SECTION2/SECTION3/SECTION4"));
|
||||
|
||||
ON_CALL(application, GetApplicationId())
|
||||
.WillByDefault(testing::Return(L""));
|
||||
|
||||
auto requestHandlerConfig = std::unique_ptr<InProcessOptions>(MockInProcessOptions::CreateConfig());
|
||||
IN_PROCESS_APPLICATION *app = new IN_PROCESS_APPLICATION(server, application, std::move(requestHandlerConfig), nullptr, 0);
|
||||
|
||||
ASSERT_STREQ(app->QueryApplicationVirtualPath().c_str(), L"/");
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
DECLARE_DEBUG_PRINT_OBJECT2("tests", ASPNETCORE_DEBUG_FLAG_INFO | ASPNETCORE_DEBUG_FLAG_CONSOLE);
|
||||
|
||||
int wmain(int argc, wchar_t* argv[])
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
RUN_ALL_TESTS();
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <Windows.h>
|
||||
#include <atlbase.h>
|
||||
#include <pdh.h>
|
||||
#include <vector>
|
||||
#include <Shlobj.h>
|
||||
#include <httpserv.h>
|
||||
#include <winhttp.h>
|
||||
#include <httptrace.h>
|
||||
#include <cstdlib>
|
||||
#include <wchar.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
#include <hashfn.h>
|
||||
#include <hashtable.h>
|
||||
#include "stringa.h"
|
||||
#include "stringu.h"
|
||||
#include "dbgutil.h"
|
||||
#include "ahutil.h"
|
||||
#include "multisz.h"
|
||||
#include "multisza.h"
|
||||
#include "base64.h"
|
||||
#include <listentry.h>
|
||||
#include <datetime.h>
|
||||
#include <reftrace.h>
|
||||
#include <acache.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "stringu.h"
|
||||
#include "stringa.h"
|
||||
#include "multisz.h"
|
||||
#include "dbgutil.h"
|
||||
#include "hashfn.h"
|
||||
|
||||
#include "requesthandler_config.h"
|
||||
#include "hostfxr_utility.h"
|
||||
#include "config_utility.h"
|
||||
#include "environmentvariablehash.h"
|
||||
#include "iapplication.h"
|
||||
#include "debugutil.h"
|
||||
#include "requesthandler.h"
|
||||
#include "resources.h"
|
||||
#include "aspnetcore_msg.h"
|
||||
#include "Helpers.h"
|
||||
#include "GlobalVersionUtility.h"
|
||||
|
||||
#undef assert // Macro redefinition in IISLib.
|
||||
#include "gtest/gtest.h"
|
||||
#include "fakeclasses.h"
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Environment.h"
|
||||
#include "StringHelpers.h"
|
||||
|
||||
TEST(PassUnexpandedEnvString, ExpandsResult)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
PCWSTR unexpandedString = L"ANCM_TEST_ENV_VAR";
|
||||
PCWSTR unexpandedStringValue = L"foobar";
|
||||
STRU struExpandedString;
|
||||
SetEnvironmentVariable(L"ANCM_TEST_ENV_VAR", unexpandedStringValue);
|
||||
|
||||
hr = struExpandedString.CopyAndExpandEnvironmentStrings(L"%ANCM_TEST_ENV_VAR%");
|
||||
EXPECT_EQ(hr, S_OK);
|
||||
EXPECT_STREQ(L"foobar", struExpandedString.QueryStr());
|
||||
}
|
||||
|
||||
TEST(PassUnexpandedEnvString, LongStringExpandsResults)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
PCWSTR unexpandedString = L"ANCM_TEST_ENV_VAR_LONG";
|
||||
STRU struStringValue;
|
||||
STACK_STRU(struExpandedString, MAX_PATH);
|
||||
|
||||
struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize");
|
||||
struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize");
|
||||
struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize");
|
||||
struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize");
|
||||
struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize");
|
||||
struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize");
|
||||
|
||||
SetEnvironmentVariable(unexpandedString, struStringValue.QueryStr());
|
||||
|
||||
hr = struExpandedString.CopyAndExpandEnvironmentStrings(L"%ANCM_TEST_ENV_VAR_LONG%");
|
||||
EXPECT_EQ(hr, S_OK);
|
||||
EXPECT_EQ(struStringValue.QueryCCH(), struExpandedString.QueryCCH());
|
||||
// The values are exactly the same, however EXPECT_EQ is returning false.
|
||||
//EXPECT_EQ(struStringValue.QueryStr(), struExpandedString.QueryStr());
|
||||
EXPECT_STREQ(struStringValue.QueryStr(), struExpandedString.QueryStr());
|
||||
}
|
||||
|
||||
|
||||
TEST(GetEnvironmentVariableValue, ReturnsCorrectLenght)
|
||||
{
|
||||
SetEnvironmentVariable(L"RANDOM_ENV_VAR_1", L"test");
|
||||
|
||||
auto result = Environment::GetEnvironmentVariableValue(L"RANDOM_ENV_VAR_1");
|
||||
EXPECT_TRUE(result.has_value());
|
||||
EXPECT_EQ(result.value().length(), 4);
|
||||
EXPECT_STREQ(result.value().c_str(), L"test");
|
||||
}
|
||||
|
||||
|
||||
TEST(GetEnvironmentVariableValue, ReturnsNulloptWhenNotFound)
|
||||
{
|
||||
auto result = Environment::GetEnvironmentVariableValue(L"RANDOM_ENV_VAR_2");
|
||||
EXPECT_FALSE(result.has_value());
|
||||
}
|
||||
|
||||
TEST(CheckStringHelpers, FormatWithoutContentDoesNotIncreaseSizeString)
|
||||
{
|
||||
std::string testString = "test";
|
||||
auto result = format(testString);
|
||||
EXPECT_EQ(testString.size(), result.size());
|
||||
}
|
||||
|
||||
TEST(CheckStringHelpers, FormatWithoutContentDoesNotIncreaseSizeWstring)
|
||||
{
|
||||
std::wstring testString = L"test";
|
||||
auto result = format(testString);
|
||||
EXPECT_EQ(testString.size(), result.size());
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<Project>
|
||||
<Import Project="..\Directory.Build.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- These tests are remaining at netcoreapp2.2 because the Benchmarks and functional tests use the same websites.
|
||||
We must leave the benchmarks at 2.1, and if you try to import a project that uses 22 to a 21 project it complains. -->
|
||||
<DeveloperBuildTestTfms>netcoreapp2.2</DeveloperBuildTestTfms>
|
||||
<StandardTestTfms>$(DeveloperBuildTestTfms)</StandardTestTfms>
|
||||
<StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' ">$(StandardTestTfms)</StandardTestTfms>
|
||||
<StandardTestTfms Condition=" '$(DeveloperBuild)' != 'true' AND '$(OS)' == 'Windows_NT' ">$(StandardTestTfms);net461</StandardTestTfms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Internal.AspNetCore.Sdk" PrivateAssets="All" Version="$(InternalAspNetCoreSdkPackageVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,39 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class BackwardsCompatibilityTests : FixtureLoggedTest
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public BackwardsCompatibilityTests(IISTestSiteFixture fixture) : base(fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task CheckBackwardsCompatibilityIsUsed()
|
||||
{
|
||||
var response = await _fixture.Client.GetAsync("/HelloWorld");
|
||||
var handles = _fixture.DeploymentResult.HostProcess.Modules;
|
||||
|
||||
foreach (ProcessModule handle in handles)
|
||||
{
|
||||
if (handle.ModuleName == "aspnetcorev2.dll")
|
||||
{
|
||||
Assert.Equal("12.2.18287.0", handle.FileVersionInfo.FileVersion);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new XunitException($"Could not find aspnetcorev2.dll loaded in process {_fixture.DeploymentResult.HostProcess.ProcessName}");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public static class DeployerSelector
|
||||
{
|
||||
public static ServerType ServerType => ServerType.IIS;
|
||||
public static bool IsBackwardsCompatiblityTest => true;
|
||||
public static bool IsForwardsCompatibilityTest => false;
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.2</TargetFrameworks>
|
||||
<TestGroupName>IISBackwardsCompatibility.FunctionalTests</TestGroupName>
|
||||
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\Common.FunctionalTests\AppHostConfig\*.config" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj" />
|
||||
<ProjectReference Include="..\Common.Tests\Common.Tests.csproj" />
|
||||
<ProjectReference Include="..\WebSites\InProcessWebSite\InProcessWebSite.csproj">
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\WebSites\OutOfProcessWebSite\OutOfProcessWebSite.csproj">
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\WebSites\StressTestWebSite\StressTestWebSite.csproj">
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Common.FunctionalTests\**\*.cs" />
|
||||
<Compile Include="..\IIS.Shared.FunctionalTests\**\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.AspNetCoreModule" Version="$(MicrosoftAspNetCoreAspNetCoreModuleStablePackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.AspNetCoreModuleV2" Version="$(MicrosoftAspNetCoreAspNetCoreModuleV2StablePackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IntegrationTesting" Version="$(MicrosoftAspNetCoreServerIntegrationTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
|
||||
<PackageReference Include="System.Diagnostics.EventLog" Version="$(SystemDiagnosticsEventLogPackageVersion)" />
|
||||
<PackageReference Include="System.Net.WebSockets.WebSocketProtocol" Version="$(SystemNetWebSocketsWebSocketProtocolPackageVersion)" />
|
||||
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualStudioPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public static class DeployerSelector
|
||||
{
|
||||
public static ServerType ServerType => ServerType.IIS;
|
||||
public static bool IsBackwardsCompatiblityTest => false;
|
||||
public static bool IsForwardsCompatibilityTest => true;
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(IISTestSiteCollection.Name)]
|
||||
public class ForwardsCompatibilityTests : FixtureLoggedTest
|
||||
{
|
||||
private readonly IISTestSiteFixture _fixture;
|
||||
|
||||
public ForwardsCompatibilityTests(IISTestSiteFixture fixture) : base(fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task CheckForwardsCompatibilityIsUsed()
|
||||
{
|
||||
var response = await _fixture.Client.GetAsync("/HelloWorld");
|
||||
var handles = _fixture.DeploymentResult.HostProcess.Modules;
|
||||
foreach (ProcessModule handle in handles)
|
||||
{
|
||||
if (handle.ModuleName == "aspnetcorev2_inprocess.dll")
|
||||
{
|
||||
Assert.Equal("12.2.18287.0", handle.FileVersionInfo.FileVersion);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new XunitException($"Could not find aspnetcorev2_inprocess.dll loaded in process {_fixture.DeploymentResult.HostProcess.ProcessName}");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.2</TargetFrameworks>
|
||||
<TestGroupName>IISForwardsCompatibility.FunctionalTests</TestGroupName>
|
||||
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\Common.FunctionalTests\AppHostConfig\*.config" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Common.Tests\Common.Tests.csproj" />
|
||||
<ProjectReference Include="..\WebSites\InProcessForwardsCompatWebSite\InProcessWebSite.csproj">
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\WebSites\OutOfProcessWebSite\OutOfProcessWebSite.csproj">
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\WebSites\StressTestWebSite\StressTestWebSite.csproj">
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Common.FunctionalTests\**\*.cs" />
|
||||
<Compile Include="..\IIS.Shared.FunctionalTests\**\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\..\build\functional-test-assets.targets" />
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IntegrationTesting" Version="$(MicrosoftAspNetCoreServerIntegrationTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
|
||||
<PackageReference Include="System.Diagnostics.EventLog" Version="$(SystemDiagnosticsEventLogPackageVersion)" />
|
||||
<PackageReference Include="System.Net.WebSockets.WebSocketProtocol" Version="$(SystemNetWebSocketsWebSocketProtocolPackageVersion)" />
|
||||
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualStudioPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public static class DeployerSelector
|
||||
{
|
||||
public static ServerType ServerType => ServerType.IIS;
|
||||
public static bool IsBackwardsCompatiblityTest => false;
|
||||
public static bool IsForwardsCompatibilityTest => false;
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.2</TargetFrameworks>
|
||||
<TestGroupName>IIS.FunctionalTests</TestGroupName>
|
||||
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\Common.FunctionalTests\AppHostConfig\*.config" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj" />
|
||||
<ProjectReference Include="..\Common.Tests\Common.Tests.csproj" />
|
||||
<ProjectReference Include="..\WebSites\InProcessWebSite\InProcessWebSite.csproj">
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\WebSites\OutOfProcessWebSite\OutOfProcessWebSite.csproj">
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\WebSites\StressTestWebSite\StressTestWebSite.csproj">
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Common.FunctionalTests\**\*.cs" />
|
||||
<Compile Include="..\IIS.Shared.FunctionalTests\**\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\..\build\functional-test-assets.targets" />
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IntegrationTesting" Version="$(MicrosoftAspNetCoreServerIntegrationTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
|
||||
<PackageReference Include="System.Diagnostics.EventLog" Version="$(SystemDiagnosticsEventLogPackageVersion)" />
|
||||
<PackageReference Include="System.Net.WebSockets.WebSocketProtocol" Version="$(SystemNetWebSocketsWebSocketProtocolPackageVersion)" />
|
||||
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualStudioPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,150 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace IIS.FunctionalTests.Inprocess
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class StdOutRedirectionTests : LogFileTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public StdOutRedirectionTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[SkipIfDebug]
|
||||
public async Task FrameworkNotFoundExceptionLogged_Pipe()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
Helpers.ModifyFrameworkVersionInRuntimeConfig(deploymentResult);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
||||
Assert.False(response.IsSuccessStatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult,
|
||||
"The specified framework 'Microsoft.NETCore.App', version '2.9.9' was not found.");
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[SkipIfDebug]
|
||||
public async Task FrameworkNotFoundExceptionLogged_File()
|
||||
{
|
||||
var deploymentParameters =
|
||||
_fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
|
||||
deploymentParameters.EnableLogging(_logFolderPath);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
Helpers.ModifyFrameworkVersionInRuntimeConfig(deploymentResult);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
||||
Assert.False(response.IsSuccessStatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
var contents = Helpers.ReadAllTextFromFile(Helpers.GetExpectedLogName(deploymentResult, _logFolderPath), Logger);
|
||||
var expectedString = "The specified framework 'Microsoft.NETCore.App', version '2.9.9' was not found.";
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, expectedString);
|
||||
Assert.Contains(expectedString, contents);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
[SkipIfDebug]
|
||||
public async Task EnableCoreHostTraceLogging_TwoLogFilesCreated()
|
||||
{
|
||||
var deploymentParameters =
|
||||
_fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} CheckLargeStdOutWrites");
|
||||
|
||||
deploymentParameters.EnvironmentVariables["COREHOST_TRACE"] = "1";
|
||||
|
||||
deploymentParameters.EnableLogging(_logFolderPath);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
||||
Assert.False(response.IsSuccessStatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
var fileInDirectory = Directory.GetFiles(_logFolderPath).Single();
|
||||
var contents = Helpers.ReadAllTextFromFile(fileInDirectory, Logger);
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Invoked hostfxr");
|
||||
Assert.Contains("Invoked hostfxr", contents);
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
[SkipIfDebug]
|
||||
[InlineData("CheckLargeStdErrWrites")]
|
||||
[InlineData("CheckLargeStdOutWrites")]
|
||||
[InlineData("CheckOversizedStdErrWrites")]
|
||||
[InlineData("CheckOversizedStdOutWrites")]
|
||||
public async Task EnableCoreHostTraceLogging_PipeCaptureNativeLogs(string path)
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.EnvironmentVariables["COREHOST_TRACE"] = "1";
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} {path}");
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
||||
|
||||
Assert.False(response.IsSuccessStatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Invoked hostfxr");
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
[SkipIfDebug]
|
||||
[InlineData("CheckLargeStdErrWrites")]
|
||||
[InlineData("CheckLargeStdOutWrites")]
|
||||
[InlineData("CheckOversizedStdErrWrites")]
|
||||
[InlineData("CheckOversizedStdOutWrites")]
|
||||
public async Task EnableCoreHostTraceLogging_FileCaptureNativeLogs(string path)
|
||||
{
|
||||
var deploymentParameters =
|
||||
_fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.EnvironmentVariables["COREHOST_TRACE"] = "1";
|
||||
deploymentParameters.TransformArguments((a, _) => $"{a} {path}");
|
||||
|
||||
deploymentParameters.EnableLogging(_logFolderPath);
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
||||
Assert.False(response.IsSuccessStatusCode);
|
||||
|
||||
StopServer();
|
||||
|
||||
var fileInDirectory = Directory.GetFiles(_logFolderPath).First();
|
||||
var contents = Helpers.ReadAllTextFromFile(fileInDirectory, Logger);
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Invoked hostfxr");
|
||||
Assert.Contains("Invoked hostfxr", contents);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace IIS.FunctionalTests
|
||||
{
|
||||
public class MofFileTests
|
||||
{
|
||||
[ConditionalFact]
|
||||
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
|
||||
[RequiresIIS(IISCapability.TracingModule)]
|
||||
public void CheckMofFile()
|
||||
{
|
||||
var path = Path.Combine(TestPathUtilities.GetSolutionRootDirectory("IISIntegration"), "src", "aspnetcoremodulev2", "aspnetcore", "ancm.mof");
|
||||
var process = Process.Start("mofcomp.exe", path);
|
||||
process.WaitForExit();
|
||||
Assert.Equal(0, process.ExitCode);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Xunit;
|
||||
|
||||
[assembly: CollectionBehavior(DisableTestParallelization = true)]
|
||||
[assembly: RequiresIIS]
|
||||
[assembly: ShortClassName]
|
|
@ -1,150 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public sealed class RequiresIISAttribute : Attribute, ITestCondition
|
||||
{
|
||||
private static readonly (IISCapability Capability, string DllName)[] Modules =
|
||||
{
|
||||
(IISCapability.Websockets, "iiswsock.dll"),
|
||||
(IISCapability.WindowsAuthentication, "authsspi.dll"),
|
||||
(IISCapability.DynamicCompression, "compdyn.dll"),
|
||||
(IISCapability.ApplicationInitialization, "warmup.dll"),
|
||||
(IISCapability.TracingModule, "iisetw.dll"),
|
||||
(IISCapability.FailedRequestTracingModule, "iisfreb.dll"),
|
||||
(IISCapability.BasicAuthentication, "authbas.dll"),
|
||||
};
|
||||
|
||||
private static readonly bool _isMetStatic;
|
||||
private static readonly string _skipReasonStatic;
|
||||
private static readonly bool _poolEnvironmentVariablesAvailable;
|
||||
private static readonly IISCapability _modulesAvailable;
|
||||
|
||||
static RequiresIISAttribute()
|
||||
{
|
||||
if (Environment.GetEnvironmentVariable("ASPNETCORE_TEST_SKIP_IIS") == "true")
|
||||
{
|
||||
_skipReasonStatic = "Test skipped using ASPNETCORE_TEST_SKIP_IIS environment variable";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
_skipReasonStatic = "IIS tests can only be run on Windows";
|
||||
return;
|
||||
}
|
||||
|
||||
var identity = WindowsIdentity.GetCurrent();
|
||||
var principal = new WindowsPrincipal(identity);
|
||||
if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
|
||||
{
|
||||
_skipReasonStatic += "The current console is not running as admin.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", "w3wp.exe")))
|
||||
{
|
||||
_skipReasonStatic += "The machine does not have IIS installed.";
|
||||
return;
|
||||
}
|
||||
|
||||
var ancmConfigPath = Path.Combine(Environment.SystemDirectory, "inetsrv", "config", "schema", "aspnetcore_schema_v2.xml");
|
||||
|
||||
if (!File.Exists(ancmConfigPath))
|
||||
{
|
||||
_skipReasonStatic = "IIS Schema is not installed.";
|
||||
return;
|
||||
}
|
||||
|
||||
XDocument ancmConfig;
|
||||
|
||||
try
|
||||
{
|
||||
ancmConfig = XDocument.Load(ancmConfigPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_skipReasonStatic = "Could not read ANCM schema configuration";
|
||||
return;
|
||||
}
|
||||
|
||||
_isMetStatic = ancmConfig
|
||||
.Root
|
||||
.Descendants("attribute")
|
||||
.Any(n => "hostingModel".Equals(n.Attribute("name")?.Value, StringComparison.Ordinal));
|
||||
|
||||
_skipReasonStatic = _isMetStatic ? null : "IIS schema needs to be upgraded to support ANCM.";
|
||||
|
||||
foreach (var module in Modules)
|
||||
{
|
||||
if (File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", module.DllName)))
|
||||
{
|
||||
_modulesAvailable |= module.Capability;
|
||||
}
|
||||
}
|
||||
|
||||
var iisRegistryKey = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\InetStp", writable: false);
|
||||
if (iisRegistryKey == null)
|
||||
{
|
||||
_poolEnvironmentVariablesAvailable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var majorVersion = (int)iisRegistryKey.GetValue("MajorVersion", -1);
|
||||
var minorVersion = (int)iisRegistryKey.GetValue("MinorVersion", -1);
|
||||
var version = new Version(majorVersion, minorVersion);
|
||||
_poolEnvironmentVariablesAvailable = version >= new Version(10, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public RequiresIISAttribute()
|
||||
: this(IISCapability.None) { }
|
||||
|
||||
public RequiresIISAttribute(IISCapability capabilities)
|
||||
{
|
||||
IsMet = _isMetStatic;
|
||||
SkipReason = _skipReasonStatic;
|
||||
if (capabilities.HasFlag(IISCapability.PoolEnvironmentVariables))
|
||||
{
|
||||
IsMet &= _poolEnvironmentVariablesAvailable;
|
||||
if (!_poolEnvironmentVariablesAvailable)
|
||||
{
|
||||
SkipReason += "The machine does allow for setting environment variables on application pools.";
|
||||
}
|
||||
}
|
||||
|
||||
if (capabilities.HasFlag(IISCapability.ShutdownToken))
|
||||
{
|
||||
IsMet = false;
|
||||
SkipReason += "https://github.com/aspnet/IISIntegration/issues/1074";
|
||||
}
|
||||
|
||||
foreach (var module in Modules)
|
||||
{
|
||||
if (capabilities.HasFlag(module.Capability))
|
||||
{
|
||||
var available = _modulesAvailable.HasFlag(module.Capability);
|
||||
IsMet &= available;
|
||||
if (!available)
|
||||
{
|
||||
SkipReason += $"The machine does have {module.Capability} available.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsMet { get; }
|
||||
public string SkipReason { get; }
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.ServiceProcess;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace IIS.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class ApplicationInitializationTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public ApplicationInitializationTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[RequiresIIS(IISCapability.ApplicationInitialization)]
|
||||
[InlineData(HostingModel.InProcess)]
|
||||
[InlineData(HostingModel.OutOfProcess)]
|
||||
public async Task ApplicationPreloadStartsApp(HostingModel hostingModel)
|
||||
{
|
||||
// This test often hits a memory leak in warmup.dll module, it has been reported to IIS team
|
||||
using (AppVerifier.Disable(DeployerSelector.ServerType, 0x900))
|
||||
{
|
||||
var baseDeploymentParameters = _fixture.GetBaseDeploymentParameters(hostingModel, publish: true);
|
||||
baseDeploymentParameters.TransformArguments(
|
||||
(args, contentRoot) => $"{args} CreateFile \"{Path.Combine(contentRoot, "Started.txt")}\"");
|
||||
EnablePreload(baseDeploymentParameters);
|
||||
|
||||
var result = await DeployAsync(baseDeploymentParameters);
|
||||
|
||||
await Helpers.Retry(async () => await File.ReadAllTextAsync(Path.Combine(result.ContentRoot, "Started.txt")), 10, 200);
|
||||
StopServer();
|
||||
EventLogHelpers.VerifyEventLogEvent(result, EventLogHelpers.Started(result));
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalTheory]
|
||||
[RequiresIIS(IISCapability.ApplicationInitialization)]
|
||||
[InlineData(HostingModel.InProcess)]
|
||||
[InlineData(HostingModel.OutOfProcess)]
|
||||
public async Task ApplicationInitializationPageIsRequested(HostingModel hostingModel)
|
||||
{
|
||||
// This test often hits a memory leak in warmup.dll module, it has been reported to IIS team
|
||||
using (AppVerifier.Disable(DeployerSelector.ServerType, 0x900))
|
||||
{
|
||||
var baseDeploymentParameters = _fixture.GetBaseDeploymentParameters(hostingModel, publish: true);
|
||||
EnablePreload(baseDeploymentParameters);
|
||||
|
||||
baseDeploymentParameters.ServerConfigActionList.Add(
|
||||
(config, _) => {
|
||||
config
|
||||
.RequiredElement("system.webServer")
|
||||
.GetOrAdd("applicationInitialization")
|
||||
.GetOrAdd("add", "initializationPage", "/CreateFile");
|
||||
});
|
||||
|
||||
var result = await DeployAsync(baseDeploymentParameters);
|
||||
|
||||
await Helpers.Retry(async () => await File.ReadAllTextAsync(Path.Combine(result.ContentRoot, "Started.txt")), 10, 200);
|
||||
StopServer();
|
||||
EventLogHelpers.VerifyEventLogEvent(result, EventLogHelpers.Started(result));
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnablePreload(IISDeploymentParameters baseDeploymentParameters)
|
||||
{
|
||||
baseDeploymentParameters.EnsureSection("applicationInitialization", "system.webServer");
|
||||
baseDeploymentParameters.ServerConfigActionList.Add(
|
||||
(config, _) => {
|
||||
|
||||
config
|
||||
.RequiredElement("system.applicationHost")
|
||||
.RequiredElement("sites")
|
||||
.RequiredElement("site")
|
||||
.RequiredElement("application")
|
||||
.SetAttributeValue("preloadEnabled", true);
|
||||
});
|
||||
|
||||
baseDeploymentParameters.EnableModule("ApplicationInitializationModule", "%IIS_BIN%\\warmup.dll");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,198 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
IIS configuration sections.
|
||||
|
||||
For schema documentation, see
|
||||
%windir%\system32\inetsrv\config\schema\IIS_schema.xml.
|
||||
|
||||
Please make a backup of this file before making any changes to it.
|
||||
|
||||
-->
|
||||
|
||||
<configuration>
|
||||
|
||||
<!--
|
||||
|
||||
The <configSections> section controls the registration of sections.
|
||||
Section is the basic unit of deployment, locking, searching and
|
||||
containment for configuration settings.
|
||||
|
||||
Every section belongs to one section group.
|
||||
A section group is a container of logically-related sections.
|
||||
|
||||
Sections cannot be nested.
|
||||
Section groups may be nested.
|
||||
|
||||
<section
|
||||
name="" [Required, Collection Key] [XML name of the section]
|
||||
allowDefinition="Everywhere" [MachineOnly|MachineToApplication|AppHostOnly|Everywhere] [Level where it can be set]
|
||||
overrideModeDefault="Allow" [Allow|Deny] [Default delegation mode]
|
||||
allowLocation="true" [true|false] [Allowed in location tags]
|
||||
/>
|
||||
|
||||
The recommended way to unlock sections is by using a location tag:
|
||||
<location path="Default Web Site" overrideMode="Allow">
|
||||
<system.webServer>
|
||||
<asp />
|
||||
</system.webServer>
|
||||
</location>
|
||||
|
||||
-->
|
||||
<configSections>
|
||||
<sectionGroup name="system.applicationHost">
|
||||
<section name="applicationPools" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="configHistory" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="customMetadata" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="listenerAdapters" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="log" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="serviceAutoStartProviders" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="sites" overrideModeDefault="Allow" />
|
||||
<section name="webLimits" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
|
||||
<sectionGroup name="system.webServer">
|
||||
<section name="asp" overrideModeDefault="Deny" />
|
||||
<section name="caching" overrideModeDefault="Allow" />
|
||||
<section name="aspNetCore" overrideModeDefault="Allow" />
|
||||
<section name="cgi" overrideModeDefault="Deny" />
|
||||
<section name="defaultDocument" overrideModeDefault="Allow" />
|
||||
<section name="directoryBrowse" overrideModeDefault="Allow" />
|
||||
<section name="fastCgi" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="globalModules" overrideModeDefault="Allow" />
|
||||
<section name="handlers" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />
|
||||
<section name="httpCompression" overrideModeDefault="Allow" />
|
||||
<section name="httpErrors" overrideModeDefault="Allow" />
|
||||
<section name="httpLogging" overrideModeDefault="Deny" />
|
||||
<section name="httpProtocol" overrideModeDefault="Allow" />
|
||||
<section name="httpRedirect" overrideModeDefault="Allow" />
|
||||
<section name="httpTracing" overrideModeDefault="Deny" />
|
||||
<section name="isapiFilters" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
|
||||
<section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
|
||||
<section name="applicationInitialization" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />
|
||||
<section name="odbcLogging" overrideModeDefault="Deny" />
|
||||
<sectionGroup name="security">
|
||||
<section name="access" overrideModeDefault="Deny" />
|
||||
<section name="applicationDependencies" overrideModeDefault="Deny" />
|
||||
<sectionGroup name="authentication">
|
||||
<section name="anonymousAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="basicAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="clientCertificateMappingAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="digestAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="iisClientCertificateMappingAuthentication" overrideModeDefault="Deny" />
|
||||
<section name="windowsAuthentication" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
<section name="authorization" overrideModeDefault="Allow" />
|
||||
<section name="ipSecurity" overrideModeDefault="Deny" />
|
||||
<section name="dynamicIpSecurity" overrideModeDefault="Deny" />
|
||||
<section name="isapiCgiRestriction" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||
<section name="requestFiltering" overrideModeDefault="Allow" />
|
||||
</sectionGroup>
|
||||
<section name="serverRuntime" overrideModeDefault="Deny" />
|
||||
<section name="serverSideInclude" overrideModeDefault="Deny" />
|
||||
<section name="staticContent" overrideModeDefault="Allow" />
|
||||
<sectionGroup name="tracing">
|
||||
<section name="traceFailedRequests" overrideModeDefault="Allow" />
|
||||
<section name="traceProviderDefinitions" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
<section name="urlCompression" overrideModeDefault="Allow" />
|
||||
<section name="validation" overrideModeDefault="Allow" />
|
||||
<sectionGroup name="webdav">
|
||||
<section name="globalSettings" overrideModeDefault="Deny" />
|
||||
<section name="authoring" overrideModeDefault="Deny" />
|
||||
<section name="authoringRules" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
<section name="webSocket" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
<sectionGroup name="system.ftpServer">
|
||||
<section name="log" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||
<section name="firewallSupport" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||
<section name="caching" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||
<section name="providerDefinitions" overrideModeDefault="Deny" />
|
||||
<sectionGroup name="security">
|
||||
<section name="ipSecurity" overrideModeDefault="Deny" />
|
||||
<section name="requestFiltering" overrideModeDefault="Deny" />
|
||||
<section name="authorization" overrideModeDefault="Deny" />
|
||||
<section name="authentication" overrideModeDefault="Deny" />
|
||||
</sectionGroup>
|
||||
<section name="serverRuntime" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<system.applicationHost>
|
||||
|
||||
<applicationPools>
|
||||
<add name="DefaultAppPool" />
|
||||
<applicationPoolDefaults managedRuntimeVersion="v4.0">
|
||||
<processModel identityType="ApplicationPoolIdentity" />
|
||||
</applicationPoolDefaults>
|
||||
</applicationPools>
|
||||
|
||||
<!--
|
||||
|
||||
The <customMetadata> section is used internally by the Admin Base Objects
|
||||
(ABO) Compatibility component. Please do not modify its content.
|
||||
|
||||
-->
|
||||
<customMetadata />
|
||||
|
||||
<!--
|
||||
|
||||
The <listenerAdapters> section defines the protocols with which the
|
||||
Windows Process Activation Service (WAS) binds.
|
||||
|
||||
-->
|
||||
<listenerAdapters>
|
||||
<add name="http" />
|
||||
</listenerAdapters>
|
||||
|
||||
<log>
|
||||
<centralBinaryLogFile enabled="false" />
|
||||
<centralW3CLogFile enabled="false" />
|
||||
</log>
|
||||
|
||||
<sites>
|
||||
<site name="Default Web Site" id="1">
|
||||
<application path="/">
|
||||
<virtualDirectory path="/" physicalPath="." />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation="*:50691:localhost" />
|
||||
</bindings>
|
||||
</site>
|
||||
<applicationDefaults applicationPool="DefaultAppPool" />
|
||||
<virtualDirectoryDefaults allowSubDirConfig="true" />
|
||||
</sites>
|
||||
|
||||
<webLimits />
|
||||
|
||||
</system.applicationHost>
|
||||
|
||||
<system.webServer>
|
||||
|
||||
<!--
|
||||
|
||||
The <globalModules> section defines all native-code modules.
|
||||
To enable a module, specify it in the <modules> section.
|
||||
|
||||
-->
|
||||
<globalModules>
|
||||
<add name="AnonymousAuthenticationModule" image="%windir%\System32\inetsrv\authanon.dll" />
|
||||
<add name="AspNetCoreModuleV2" image="aspnetcorev2.dll" />
|
||||
</globalModules>
|
||||
|
||||
<handlers accessPolicy="Read, Script">
|
||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
|
||||
</handlers>
|
||||
|
||||
|
||||
<modules>
|
||||
<add name="AnonymousAuthenticationModule" lockItem="true" />
|
||||
<add name="AspNetCoreModuleV2" lockItem="true" />
|
||||
</modules>
|
||||
|
||||
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" hostingModel="inprocess" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
|
||||
|
||||
</system.webServer>
|
||||
|
||||
</configuration>
|
|
@ -1,302 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Connections;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[SkipIfHostableWebCoreNotAvailable]
|
||||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")]
|
||||
public class ClientDisconnectTests : StrictTestServerTests
|
||||
{
|
||||
[ConditionalFact]
|
||||
public async Task WritesSucceedAfterClientDisconnect()
|
||||
{
|
||||
var requestStartedCompletionSource = CreateTaskCompletionSource();
|
||||
var clientDisconnectedCompletionSource = CreateTaskCompletionSource();
|
||||
var requestCompletedCompletionSource = CreateTaskCompletionSource();
|
||||
|
||||
var data = new byte[1024];
|
||||
using (var testServer = await TestServer.Create(
|
||||
async ctx =>
|
||||
{
|
||||
requestStartedCompletionSource.SetResult(true);
|
||||
await clientDisconnectedCompletionSource.Task;
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
await ctx.Response.Body.WriteAsync(data);
|
||||
}
|
||||
|
||||
requestCompletedCompletionSource.SetResult(true);
|
||||
}, LoggerFactory))
|
||||
{
|
||||
using (var connection = testServer.CreateConnection())
|
||||
{
|
||||
await SendContentLength1Post(connection);
|
||||
await requestStartedCompletionSource.Task.DefaultTimeout();
|
||||
}
|
||||
clientDisconnectedCompletionSource.SetResult(true);
|
||||
|
||||
await requestCompletedCompletionSource.Task.DefaultTimeout();
|
||||
}
|
||||
|
||||
AssertConnectionDisconnectLog();
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task WritesCancelledWhenUsingAbortedToken()
|
||||
{
|
||||
var requestStartedCompletionSource = CreateTaskCompletionSource();
|
||||
var requestCompletedCompletionSource = CreateTaskCompletionSource();
|
||||
|
||||
Exception exception = null;
|
||||
|
||||
var data = new byte[1];
|
||||
using (var testServer = await TestServer.Create(async ctx =>
|
||||
{
|
||||
requestStartedCompletionSource.SetResult(true);
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
await ctx.Response.Body.WriteAsync(data, ctx.RequestAborted);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exception = e;
|
||||
}
|
||||
|
||||
requestCompletedCompletionSource.SetResult(true);
|
||||
}, LoggerFactory))
|
||||
{
|
||||
using (var connection = testServer.CreateConnection())
|
||||
{
|
||||
await SendContentLength1Post(connection);
|
||||
|
||||
await requestStartedCompletionSource.Task.DefaultTimeout();
|
||||
}
|
||||
|
||||
await requestCompletedCompletionSource.Task.DefaultTimeout();
|
||||
|
||||
Assert.IsType<OperationCanceledException>(exception);
|
||||
}
|
||||
|
||||
AssertConnectionDisconnectLog();
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ReadThrowsAfterClientDisconnect()
|
||||
{
|
||||
var requestStartedCompletionSource = CreateTaskCompletionSource();
|
||||
var requestCompletedCompletionSource = CreateTaskCompletionSource();
|
||||
|
||||
Exception exception = null;
|
||||
|
||||
var data = new byte[1024];
|
||||
using (var testServer = await TestServer.Create(async ctx =>
|
||||
{
|
||||
requestStartedCompletionSource.SetResult(true);
|
||||
try
|
||||
{
|
||||
await ctx.Request.Body.ReadAsync(data);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exception = e;
|
||||
}
|
||||
|
||||
requestCompletedCompletionSource.SetResult(true);
|
||||
}, LoggerFactory))
|
||||
{
|
||||
using (var connection = testServer.CreateConnection())
|
||||
{
|
||||
await SendContentLength1Post(connection);
|
||||
await requestStartedCompletionSource.Task.DefaultTimeout();
|
||||
}
|
||||
|
||||
await requestCompletedCompletionSource.Task.DefaultTimeout();
|
||||
}
|
||||
|
||||
Assert.IsType<ConnectionResetException>(exception);
|
||||
Assert.Equal("The client has disconnected", exception.Message);
|
||||
|
||||
AssertConnectionDisconnectLog();
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task WriterThrowsCancelledException()
|
||||
{
|
||||
var requestStartedCompletionSource = CreateTaskCompletionSource();
|
||||
var requestCompletedCompletionSource = CreateTaskCompletionSource();
|
||||
|
||||
Exception exception = null;
|
||||
var cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
var data = new byte[1];
|
||||
using (var testServer = await TestServer.Create(async ctx =>
|
||||
{
|
||||
requestStartedCompletionSource.SetResult(true);
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
await ctx.Response.Body.WriteAsync(data, cancellationTokenSource.Token);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exception = e;
|
||||
}
|
||||
|
||||
requestCompletedCompletionSource.SetResult(true);
|
||||
}, LoggerFactory))
|
||||
{
|
||||
using (var connection = testServer.CreateConnection())
|
||||
{
|
||||
await SendContentLength1Post(connection);
|
||||
|
||||
await requestStartedCompletionSource.Task.DefaultTimeout();
|
||||
cancellationTokenSource.Cancel();
|
||||
await requestCompletedCompletionSource.Task.DefaultTimeout();
|
||||
}
|
||||
|
||||
Assert.IsType<OperationCanceledException>(exception);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ReaderThrowsCancelledException()
|
||||
{
|
||||
var requestStartedCompletionSource = CreateTaskCompletionSource();
|
||||
var requestCompletedCompletionSource = CreateTaskCompletionSource();
|
||||
|
||||
Exception exception = null;
|
||||
var cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
var data = new byte[1024];
|
||||
using (var testServer = await TestServer.Create(async ctx =>
|
||||
{
|
||||
requestStartedCompletionSource.SetResult(true);
|
||||
try
|
||||
{
|
||||
await ctx.Request.Body.ReadAsync(data, cancellationTokenSource.Token);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exception = e;
|
||||
}
|
||||
|
||||
requestCompletedCompletionSource.SetResult(true);
|
||||
}, LoggerFactory))
|
||||
{
|
||||
using (var connection = testServer.CreateConnection())
|
||||
{
|
||||
await SendContentLength1Post(connection);
|
||||
await requestStartedCompletionSource.Task.DefaultTimeout();
|
||||
cancellationTokenSource.Cancel();
|
||||
await requestCompletedCompletionSource.Task.DefaultTimeout();
|
||||
}
|
||||
Assert.IsType<OperationCanceledException>(exception);
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ReaderThrowsResetExceptionOnInvalidBody()
|
||||
{
|
||||
var requestStartedCompletionSource = CreateTaskCompletionSource();
|
||||
var requestCompletedCompletionSource = CreateTaskCompletionSource();
|
||||
|
||||
Exception exception = null;
|
||||
|
||||
var data = new byte[1024];
|
||||
using (var testServer = await TestServer.Create(async ctx =>
|
||||
{
|
||||
requestStartedCompletionSource.SetResult(true);
|
||||
try
|
||||
{
|
||||
await ctx.Request.Body.ReadAsync(data);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exception = e;
|
||||
}
|
||||
|
||||
requestCompletedCompletionSource.SetResult(true);
|
||||
}, LoggerFactory))
|
||||
{
|
||||
using (var connection = testServer.CreateConnection())
|
||||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Transfer-Encoding: chunked",
|
||||
"Host: localhost",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
|
||||
await requestStartedCompletionSource.Task;
|
||||
await connection.Send(
|
||||
"ZZZZZZZZZZZZZ");
|
||||
|
||||
await connection.Receive(
|
||||
"HTTP/1.1 400 Bad Request",
|
||||
""
|
||||
);
|
||||
|
||||
}
|
||||
await requestCompletedCompletionSource.Task.DefaultTimeout();
|
||||
}
|
||||
|
||||
Assert.IsType<ConnectionResetException>(exception);
|
||||
Assert.Equal("The client has disconnected", exception.Message);
|
||||
AssertConnectionDisconnectLog();
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RequestAbortedIsTrippedWithoutIO()
|
||||
{
|
||||
var requestStarted = CreateTaskCompletionSource();
|
||||
var requestAborted = CreateTaskCompletionSource();
|
||||
|
||||
using (var testServer = await TestServer.Create(
|
||||
async ctx => {
|
||||
ctx.RequestAborted.Register(() => requestAborted.SetResult(true));
|
||||
requestStarted.SetResult(true);
|
||||
await requestAborted.Task;
|
||||
}, LoggerFactory))
|
||||
{
|
||||
using (var connection = testServer.CreateConnection())
|
||||
{
|
||||
await SendContentLength1Post(connection);
|
||||
await requestStarted.Task;
|
||||
}
|
||||
await requestAborted.Task;
|
||||
}
|
||||
|
||||
AssertConnectionDisconnectLog();
|
||||
}
|
||||
|
||||
private void AssertConnectionDisconnectLog()
|
||||
{
|
||||
Assert.Single(TestSink.Writes, w => w.EventId.Name == "ConnectionDisconnect");
|
||||
}
|
||||
|
||||
private static async Task SendContentLength1Post(TestConnection connection)
|
||||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Content-Length: 1",
|
||||
"Host: localhost",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[SkipIfHostableWebCoreNotAvailable]
|
||||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")]
|
||||
public class HttpBodyControlFeatureTests : StrictTestServerTests
|
||||
{
|
||||
[ConditionalFact]
|
||||
public async Task ThrowsOnSyncReadOrWrite()
|
||||
{
|
||||
Exception writeException = null;
|
||||
Exception readException = null;
|
||||
using (var testServer = await TestServer.Create(
|
||||
ctx => {
|
||||
var bodyControl = ctx.Features.Get<IHttpBodyControlFeature>();
|
||||
bodyControl.AllowSynchronousIO = false;
|
||||
|
||||
try
|
||||
{
|
||||
ctx.Response.Body.Write(new byte[10]);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
writeException = ex;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ctx.Request.Body.Read(new byte[10]);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
readException = ex;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}, LoggerFactory))
|
||||
{
|
||||
await testServer.HttpClient.GetStringAsync("/");
|
||||
}
|
||||
|
||||
Assert.IsType<InvalidOperationException>(readException);
|
||||
Assert.IsType<InvalidOperationException>(writeException);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[SkipIfHostableWebCoreNotAvailable]
|
||||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")]
|
||||
public class ConnectionIdFeatureTests : StrictTestServerTests
|
||||
{
|
||||
[ConditionalFact]
|
||||
public async Task ProvidesConnectionId()
|
||||
{
|
||||
string connectionId = null;
|
||||
using (var testServer = await TestServer.Create(ctx => {
|
||||
var connectionIdFeature = ctx.Features.Get<IHttpConnectionFeature>();
|
||||
connectionId = connectionIdFeature.ConnectionId;
|
||||
return Task.CompletedTask;
|
||||
}, LoggerFactory))
|
||||
{
|
||||
await testServer.HttpClient.GetStringAsync("/");
|
||||
}
|
||||
|
||||
Assert.NotNull(connectionId);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.2</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\..\build\functional-test-assets.targets" />
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj" />
|
||||
<ProjectReference Include="..\Common.Tests\Common.Tests.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IntegrationTesting" Version="$(MicrosoftAspNetCoreServerIntegrationTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
|
||||
<PackageReference Include="System.Diagnostics.EventLog" Version="$(SystemDiagnosticsEventLogPackageVersion)" />
|
||||
<PackageReference Include="System.Net.WebSockets.WebSocketProtocol" Version="$(SystemNetWebSocketsWebSocketProtocolPackageVersion)" />
|
||||
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualStudioPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="AppHostConfig\HostableWebCore.config" CopyToOutputDirectory="PreserveNewest" Link="%(FileName)%(Extension)" />
|
||||
<None Include="$(AspNetCoreModuleV2ShimDll)" Condition="$(PackNativeAssets) == 'true'" CopyToOutputDirectory="PreserveNewest" Link="%(FileName)%(Extension)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,151 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Connections;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[SkipIfHostableWebCoreNotAvailable]
|
||||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")]
|
||||
public class ResponseAbortTests : StrictTestServerTests
|
||||
{
|
||||
[ConditionalFact]
|
||||
public async Task ClosesWithoutSendingAnything()
|
||||
{
|
||||
using (var testServer = await TestServer.Create(
|
||||
ctx => {
|
||||
ctx.Abort();
|
||||
return Task.CompletedTask;
|
||||
}, LoggerFactory))
|
||||
{
|
||||
using (var connection = testServer.CreateConnection())
|
||||
{
|
||||
await SendContentLength1Post(connection);
|
||||
await connection.WaitForConnectionClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ClosesAfterDataSent()
|
||||
{
|
||||
var bodyReceived = CreateTaskCompletionSource();
|
||||
using (var testServer = await TestServer.Create(
|
||||
async ctx => {
|
||||
await ctx.Response.WriteAsync("Abort");
|
||||
await ctx.Response.Body.FlushAsync();
|
||||
await bodyReceived.Task.DefaultTimeout();
|
||||
ctx.Abort();
|
||||
}, LoggerFactory))
|
||||
{
|
||||
using (var connection = testServer.CreateConnection())
|
||||
{
|
||||
await SendContentLength1Post(connection);
|
||||
await connection.Receive(
|
||||
"HTTP/1.1 200 OK",
|
||||
"");
|
||||
await connection.ReceiveHeaders(
|
||||
"Transfer-Encoding: chunked");
|
||||
|
||||
await connection.ReceiveChunk("Abort");
|
||||
bodyReceived.SetResult(true);
|
||||
await connection.WaitForConnectionClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task ReadsThrowAfterAbort()
|
||||
{
|
||||
Exception exception = null;
|
||||
|
||||
using (var testServer = await TestServer.Create(
|
||||
async ctx => {
|
||||
ctx.Abort();
|
||||
try
|
||||
{
|
||||
var a = new byte[10];
|
||||
await ctx.Request.Body.ReadAsync(a);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exception = e;
|
||||
}
|
||||
}, LoggerFactory))
|
||||
{
|
||||
using (var connection = testServer.CreateConnection())
|
||||
{
|
||||
await SendContentLength1Post(connection);
|
||||
await connection.WaitForConnectionClose();
|
||||
}
|
||||
}
|
||||
|
||||
Assert.IsType<ConnectionAbortedException>(exception);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task WritesNoopAfterAbort()
|
||||
{
|
||||
Exception exception = null;
|
||||
|
||||
using (var testServer = await TestServer.Create(
|
||||
async ctx => {
|
||||
ctx.Abort();
|
||||
try
|
||||
{
|
||||
await ctx.Response.Body.WriteAsync(new byte[10]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exception = e;
|
||||
}
|
||||
}, LoggerFactory))
|
||||
{
|
||||
using (var connection = testServer.CreateConnection())
|
||||
{
|
||||
await SendContentLength1Post(connection);
|
||||
await connection.WaitForConnectionClose();
|
||||
}
|
||||
}
|
||||
|
||||
Assert.Null(exception);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RequestAbortedIsTrippedAfterAbort()
|
||||
{
|
||||
bool tokenAborted = false;
|
||||
using (var testServer = await TestServer.Create(
|
||||
ctx => {
|
||||
ctx.Abort();
|
||||
tokenAborted = ctx.RequestAborted.IsCancellationRequested;
|
||||
return Task.CompletedTask;
|
||||
}, LoggerFactory))
|
||||
{
|
||||
using (var connection = testServer.CreateConnection())
|
||||
{
|
||||
await SendContentLength1Post(connection);
|
||||
await connection.WaitForConnectionClose();
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True(tokenAborted);
|
||||
}
|
||||
|
||||
private static async Task SendContentLength1Post(TestConnection connection)
|
||||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Content-Length: 1",
|
||||
"Host: localhost",
|
||||
"",
|
||||
"");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public class StrictTestServerTests: LoggedTest
|
||||
{
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
Assert.DoesNotContain(TestSink.Writes, w => w.LogLevel > LogLevel.Information);
|
||||
}
|
||||
|
||||
protected static TaskCompletionSource<bool> CreateTaskCompletionSource()
|
||||
{
|
||||
return new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[SkipIfHostableWebCoreNotAvailable]
|
||||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")]
|
||||
public class TestServerTest : StrictTestServerTests
|
||||
{
|
||||
[ConditionalFact]
|
||||
public async Task SingleProcessTestServer_HelloWorld()
|
||||
{
|
||||
var helloWorld = "Hello World";
|
||||
var expectedPath = "/Path";
|
||||
|
||||
string path = null;
|
||||
using (var testServer = await TestServer.Create(ctx =>
|
||||
{
|
||||
path = ctx.Request.Path.ToString();
|
||||
return ctx.Response.WriteAsync(helloWorld);
|
||||
}, LoggerFactory))
|
||||
{
|
||||
var result = await testServer.HttpClient.GetAsync(expectedPath);
|
||||
Assert.Equal(helloWorld, await result.Content.ReadAsStringAsync());
|
||||
Assert.Equal(expectedPath, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public sealed class SkipIfHostableWebCoreNotAvailableAttribute : Attribute, ITestCondition
|
||||
{
|
||||
public bool IsMet { get; } = File.Exists(TestServer.HostableWebCoreLocation);
|
||||
|
||||
public string SkipReason { get; } = $"Hostable Web Core not available, {TestServer.HostableWebCoreLocation} not found.";
|
||||
}
|
||||
}
|
|
@ -1,211 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Loader;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.Common;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public class TestServer: IDisposable, IStartup
|
||||
{
|
||||
private const string InProcessHandlerDll = "aspnetcorev2_inprocess.dll";
|
||||
private const string AspNetCoreModuleDll = "aspnetcorev2.dll";
|
||||
private const string HWebCoreDll = "hwebcore.dll";
|
||||
|
||||
internal static string HostableWebCoreLocation => Environment.ExpandEnvironmentVariables($@"%windir%\system32\inetsrv\{HWebCoreDll}");
|
||||
internal static string BasePath => Path.GetDirectoryName(new Uri(typeof(TestServer).Assembly.CodeBase).AbsolutePath);
|
||||
|
||||
internal static string AspNetCoreModuleLocation => Path.Combine(BasePath, AspNetCoreModuleDll);
|
||||
|
||||
private static readonly SemaphoreSlim WebCoreLock = new SemaphoreSlim(1, 1);
|
||||
|
||||
private static readonly int PortRetryCount = 10;
|
||||
|
||||
private readonly TaskCompletionSource<object> _startedTaskCompletionSource = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
private readonly Action<IApplicationBuilder> _appBuilder;
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
private readonly hostfxr_main_fn _hostfxrMainFn;
|
||||
|
||||
private Uri BaseUri => new Uri("http://localhost:" + _currentPort);
|
||||
public HttpClient HttpClient { get; private set; }
|
||||
public TestConnection CreateConnection() => new TestConnection(_currentPort);
|
||||
|
||||
private IWebHost _host;
|
||||
|
||||
private string _appHostConfigPath;
|
||||
private int _currentPort;
|
||||
|
||||
private TestServer(Action<IApplicationBuilder> appBuilder, ILoggerFactory loggerFactory)
|
||||
{
|
||||
_hostfxrMainFn = Main;
|
||||
_appBuilder = appBuilder;
|
||||
_loggerFactory = loggerFactory;
|
||||
}
|
||||
|
||||
public static async Task<TestServer> Create(Action<IApplicationBuilder> appBuilder, ILoggerFactory loggerFactory)
|
||||
{
|
||||
await WebCoreLock.WaitAsync();
|
||||
var server = new TestServer(appBuilder, loggerFactory);
|
||||
server.Start();
|
||||
(await server.HttpClient.GetAsync("/start")).EnsureSuccessStatusCode();
|
||||
await server._startedTaskCompletionSource.Task;
|
||||
return server;
|
||||
}
|
||||
|
||||
public static Task<TestServer> Create(RequestDelegate app, ILoggerFactory loggerFactory)
|
||||
{
|
||||
return Create(builder => builder.Run(app), loggerFactory);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
LoadLibrary(HostableWebCoreLocation);
|
||||
_appHostConfigPath = Path.GetTempFileName();
|
||||
|
||||
set_main_handler(_hostfxrMainFn);
|
||||
|
||||
Retry(() =>
|
||||
{
|
||||
_currentPort = TestPortHelper.GetNextPort();
|
||||
|
||||
InitializeConfig(_currentPort);
|
||||
|
||||
var startResult = WebCoreActivate(_appHostConfigPath, null, "Instance");
|
||||
if (startResult != 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Error while running WebCoreActivate: {startResult} on port {_currentPort}");
|
||||
}
|
||||
}, PortRetryCount);
|
||||
|
||||
HttpClient = new HttpClient(new LoggingHandler(new SocketsHttpHandler(), _loggerFactory.CreateLogger<TestServer>()))
|
||||
{
|
||||
BaseAddress = BaseUri
|
||||
};
|
||||
}
|
||||
|
||||
private void InitializeConfig(int port)
|
||||
{
|
||||
var webHostConfig = XDocument.Load(Path.GetFullPath("HostableWebCore.config"));
|
||||
webHostConfig.XPathSelectElement("/configuration/system.webServer/globalModules/add[@name='AspNetCoreModuleV2']")
|
||||
.SetAttributeValue("image", AspNetCoreModuleLocation);
|
||||
|
||||
var siteElement = webHostConfig.Root
|
||||
.RequiredElement("system.applicationHost")
|
||||
.RequiredElement("sites")
|
||||
.RequiredElement("site");
|
||||
|
||||
siteElement
|
||||
.RequiredElement("bindings")
|
||||
.RequiredElement("binding")
|
||||
.SetAttributeValue("bindingInformation", $":{port}:localhost");
|
||||
|
||||
webHostConfig.Save(_appHostConfigPath);
|
||||
}
|
||||
|
||||
private int Main(IntPtr argc, IntPtr argv)
|
||||
{
|
||||
_host = new WebHostBuilder()
|
||||
.UseIIS()
|
||||
.ConfigureServices(services => {
|
||||
services.AddSingleton<IStartup>(this);
|
||||
services.AddSingleton(_loggerFactory);
|
||||
})
|
||||
.UseSetting(WebHostDefaults.ApplicationKey, typeof(TestServer).GetTypeInfo().Assembly.FullName)
|
||||
.Build();
|
||||
|
||||
var doneEvent = new ManualResetEventSlim();
|
||||
var lifetime = _host.Services.GetService<IApplicationLifetime>();
|
||||
|
||||
lifetime.ApplicationStopping.Register(() => doneEvent.Set());
|
||||
_host.Start();
|
||||
_startedTaskCompletionSource.SetResult(null);
|
||||
doneEvent.Wait();
|
||||
_host.Dispose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
HttpClient.Dispose();
|
||||
|
||||
// WebCoreShutdown occasionally AVs
|
||||
// This causes the dotnet test process to crash
|
||||
// To avoid this, we have to wait to shutdown
|
||||
// and pass in true to immediately shutdown the hostable web core
|
||||
// Both of these seem to be required.
|
||||
Thread.Sleep(100);
|
||||
WebCoreShutdown(immediate: true);
|
||||
WebCoreLock.Release();
|
||||
}
|
||||
|
||||
public IServiceProvider ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.Map("/start", builder => builder.Run(context => context.Response.WriteAsync("Done")));
|
||||
_appBuilder(app);
|
||||
}
|
||||
|
||||
private delegate int hostfxr_main_fn(IntPtr argc, IntPtr argv);
|
||||
|
||||
[DllImport(HWebCoreDll)]
|
||||
private static extern int WebCoreActivate(
|
||||
[In, MarshalAs(UnmanagedType.LPWStr)]
|
||||
string appHostConfigPath,
|
||||
[In, MarshalAs(UnmanagedType.LPWStr)]
|
||||
string rootWebConfigPath,
|
||||
[In, MarshalAs(UnmanagedType.LPWStr)]
|
||||
string instanceName);
|
||||
|
||||
[DllImport(HWebCoreDll)]
|
||||
private static extern int WebCoreShutdown(bool immediate);
|
||||
|
||||
[DllImport(InProcessHandlerDll)]
|
||||
private static extern int set_main_handler(hostfxr_main_fn main);
|
||||
|
||||
[DllImport("kernel32", SetLastError=true, CharSet = CharSet.Ansi)]
|
||||
private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName);
|
||||
|
||||
private void Retry(Action func, int attempts)
|
||||
{
|
||||
var exceptions = new List<Exception>();
|
||||
|
||||
for (var attempt = 0; attempt < attempts; attempt++)
|
||||
{
|
||||
try
|
||||
{
|
||||
func();
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exceptions.Add(e);
|
||||
}
|
||||
}
|
||||
|
||||
throw new AggregateException(exceptions);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
public static class DeployerSelector
|
||||
{
|
||||
public static ServerType ServerType => ServerType.IISExpress;
|
||||
public static bool IsBackwardsCompatiblityTest => false;
|
||||
public static bool IsForwardsCompatibilityTest => false;
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.Common;
|
||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||
{
|
||||
[Collection(PublishedSitesCollection.Name)]
|
||||
public class HttpsTests : IISFunctionalTestBase
|
||||
{
|
||||
private readonly PublishedSitesFixture _fixture;
|
||||
|
||||
public HttpsTests(PublishedSitesFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
public static TestMatrix TestVariants
|
||||
=> TestMatrix.ForServers(DeployerSelector.ServerType)
|
||||
.WithTfms(Tfm.NetCoreApp22, Tfm.Net461)
|
||||
.WithAllApplicationTypes()
|
||||
.WithAllAncmVersions()
|
||||
.WithAllHostingModels();
|
||||
|
||||
[ConditionalTheory]
|
||||
[MemberData(nameof(TestVariants))]
|
||||
public async Task HttpsHelloWorld(TestVariant variant)
|
||||
{
|
||||
var port = TestPortHelper.GetNextSSLPort();
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant);
|
||||
deploymentParameters.ApplicationBaseUriHint = $"https://localhost:{port}/";
|
||||
deploymentParameters.AddHttpsToServerConfig();
|
||||
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
ServerCertificateCustomValidationCallback = (a, b, c, d) => true
|
||||
};
|
||||
var client = deploymentResult.CreateClient(handler);
|
||||
var response = await client.GetAsync("HttpsHelloWorld");
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
if (variant.HostingModel == HostingModel.OutOfProcess)
|
||||
{
|
||||
Assert.Equal("Scheme:https; Original:http", responseText);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal("Scheme:https; Original:", responseText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.2</TargetFrameworks>
|
||||
<DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\Common.FunctionalTests\AppHostConfig\*.config" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.IntegrationTesting.IIS\Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj" />
|
||||
<ProjectReference Include="..\Common.Tests\Common.Tests.csproj" />
|
||||
<ProjectReference Include="..\WebSites\**\*.csproj">
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Common.FunctionalTests\**\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\..\build\functional-test-assets.targets" />
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IntegrationTesting" Version="$(MicrosoftAspNetCoreServerIntegrationTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(MicrosoftAspNetCoreHostingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
|
||||
<PackageReference Include="System.Diagnostics.EventLog" Version="$(SystemDiagnosticsEventLogPackageVersion)" />
|
||||
<PackageReference Include="System.Net.WebSockets.WebSocketProtocol" Version="$(SystemNetWebSocketsWebSocketProtocolPackageVersion)" />
|
||||
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualStudioPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче