├── .gitattributes ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── SECURITY.md ├── docs ├── PTFUserGuide.md └── images │ ├── Demo.PNG │ ├── IncludeTag.png │ ├── TestExplorer.png │ └── TraceScenarioConfiguration.png ├── pipelines └── 1es │ ├── PTFMainSyncToGitHub.yml │ └── azure-pipelines.yml ├── samples └── XXXX_ProtocolTestSuite │ ├── XXXX_Adapter │ ├── IXXXX_Adapter.cs │ ├── IXXXX_SUTControlAdapter.cs │ ├── XXXX_Adapter.cs │ ├── XXXX_Adapter.csproj │ └── XXXX_SUTControlAdapter │ │ └── ResetSUT.ps1 │ ├── XXXX_ProtocolTestSuite.sln │ └── XXXX_TestSuite │ ├── XXXX_Scenario1.cs │ ├── XXXX_TestSuite.csproj │ ├── XXXX_TestSuite.deployment.ptfconfig │ └── XXXX_TestSuite.ptfconfig └── src ├── PTFTestLogger ├── DataType.cs ├── HtmlTestLogger.cs ├── PTFTestLogger.csproj ├── Properties │ ├── Resources.Designer.cs │ └── Resources.resx ├── Resources │ ├── casepage.css │ ├── functions.js │ ├── index.html │ └── testcase.html └── TxtToJSON.cs ├── ProtocolTestFramework.sln ├── SharedAssemblyInfo.cs ├── TestFramework.AdapterConsole ├── ConsoleHelper.cs ├── KeyHandler.cs ├── ParameterInfo.cs ├── ProcessResult.cs ├── Program.cs ├── Properties │ └── launchSettings.json └── TestFramework.AdapterConsole.csproj ├── TestFramework ├── Core │ ├── Adapters │ │ ├── AdapterProxyBase.cs │ │ ├── AdapterProxyHelpers.cs │ │ ├── DefaultValueAttribute.cs │ │ ├── Interactive │ │ │ ├── InteractiveAdapterConsole.cs │ │ │ └── InteractiveAdapterProxy.cs │ │ ├── InvokeTimeoutAttribute.cs │ │ ├── ManagedAdapterBase.cs │ │ ├── MethodHelpAttribute.cs │ │ ├── PowerShellAdapterProxy.cs │ │ └── ShellAdapterProxy.cs │ ├── Attributes │ │ ├── ProtocolTestCleanupAttribute.cs │ │ └── ProtocolTestInitializeAttribute.cs │ ├── ConfigurationDataProvider.cs │ ├── ConfigurationPropertyName.cs │ ├── ConfigurationReader.cs │ ├── DefaultTestSite.cs │ ├── IAdapter.cs │ ├── IChecker.cs │ ├── ICheckerConfig.cs │ ├── IConfigurationData.cs │ ├── ILogger.cs │ ├── IProtocolTestContext.cs │ ├── IProtocolTestNotify.cs │ ├── IProtocolTestsManager.cs │ ├── ITestLog.cs │ ├── ITestSite.cs │ ├── Logging │ │ ├── ApplicationLog.cs │ │ ├── LogInformationName.cs │ │ ├── LogProfile.cs │ │ ├── LogProfileParser.cs │ │ ├── LogProvider.cs │ │ ├── LogProviders.cs │ │ ├── LogSink.cs │ │ ├── Logger.cs │ │ ├── LoggingHelper.cs │ │ ├── Messages.cs │ │ └── Sinks │ │ │ ├── LogSinkTypes.cs │ │ │ └── PipeSink.cs │ ├── ProtocolTestsManager.cs │ ├── RequirementId.cs │ ├── TestManagerHelpers.cs │ ├── TestSiteProvider.cs │ ├── TestToolHelpers.cs │ └── Variable.cs ├── Messages │ ├── AvailableReturn.cs │ ├── EventQueue.cs │ ├── Exceptions.cs │ ├── ExpectedEvent.cs │ ├── ExpectedPreConstraint.cs │ ├── ExpectedReturn.cs │ ├── IRuntimeHost.cs │ ├── MessageRuntimeHelper.cs │ └── ObservationQueue.cs ├── Resources │ ├── Microsoft.Protocols.TestTools.AdapterConsole.runtimeconfig.json │ ├── Schema │ │ ├── TestConfig.xsd │ │ └── TestLog.xsd │ ├── packageIcon.png │ └── site.ptfconfig ├── TestFramework.csproj ├── TestFramework.nuspec ├── TestTools.cd ├── VSTS │ ├── AsynchronousErrorProcessor.cs │ ├── Checking │ │ ├── CheckException.cs │ │ ├── CheckerTypes.cs │ │ └── DefaultChecker.cs │ ├── PtfTestClassBase.cs │ ├── TestClassBase.cs │ └── VstsTestContext.cs └── build │ └── Microsoft.Protocols.TestTools.targets ├── UnitTest ├── Base.ptfconfig ├── PowerShell │ ├── CalledByAnotherScript.ps1 │ ├── NestedCall.ps1 │ ├── ReturnBool.ps1 │ ├── ReturnInt.ps1 │ ├── ReturnString.ps1 │ ├── TestTimeout.ps1 │ └── ThrowException.ps1 ├── Shell │ ├── GetPtfProp.sh │ ├── ReturnBool.sh │ ├── ReturnInt.sh │ ├── ReturnString.sh │ └── ThrowException.sh ├── TestAdapter.ptfconfig ├── TestChecker.cs ├── TestChecker.ptfconfig ├── TestInteractiveAdapter.cs ├── TestLogging.cs ├── TestLogging.ptfconfig ├── TestManagedAdapter.cs ├── TestPowerShellAdapter.cs ├── TestProperties.cs ├── TestProperties.deployment.ptfconfig ├── TestProperties.ptfconfig ├── TestPtfTestClassBase.cs ├── TestPtfTestClassBase.ptfconfig ├── TestRequirementCapture.cs ├── TestRequirementCapture.ptfconfig ├── TestShellAdapter.cs ├── UnitTest.csproj └── Utilities │ ├── PTFExpectedException.cs │ └── TestMakeStruct.cs ├── build.ps1 └── build.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | ############################################################################### 6 | # Set default behavior for command prompt diff. 7 | # 8 | # This is need for earlier builds of msysgit that does not have it on by 9 | # default for csharp files. 10 | # Note: This is only used by command line 11 | ############################################################################### 12 | #*.cs diff=csharp 13 | 14 | ############################################################################### 15 | # Set the merge driver for project and solution files 16 | # 17 | # Merging from the command prompt will add diff markers to the files if there 18 | # are conflicts (Merging from VS is not affected by the settings below, in VS 19 | # the diff markers are never inserted). Diff markers may cause the following 20 | # file extensions to fail to load in VS. An alternative would be to treat 21 | # these files as binary and thus will always conflict and require user 22 | # intervention with every merge. To do so, just uncomment the entries below 23 | ############################################################################### 24 | #*.sln merge=binary 25 | #*.csproj merge=binary 26 | #*.vbproj merge=binary 27 | #*.vcxproj merge=binary 28 | #*.vcproj merge=binary 29 | #*.dbproj merge=binary 30 | #*.fsproj merge=binary 31 | #*.lsproj merge=binary 32 | #*.wixproj merge=binary 33 | #*.modelproj merge=binary 34 | #*.sqlproj merge=binary 35 | #*.wwaproj merge=binary 36 | 37 | ############################################################################### 38 | # behavior for image files 39 | # 40 | # image files are treated as binary by default. 41 | ############################################################################### 42 | #*.jpg binary 43 | #*.png binary 44 | #*.gif binary 45 | 46 | ############################################################################### 47 | # diff behavior for common document formats 48 | # 49 | # Convert binary document formats to text before diffing them. This feature 50 | # is only available from the command line. Turn it on by uncommenting the 51 | # entries below. 52 | ############################################################################### 53 | #*.doc diff=astextplain 54 | #*.DOC diff=astextplain 55 | #*.docx diff=astextplain 56 | #*.DOCX diff=astextplain 57 | #*.dot diff=astextplain 58 | #*.DOT diff=astextplain 59 | #*.pdf diff=astextplain 60 | #*.PDF diff=astextplain 61 | #*.rtf diff=astextplain 62 | #*.RTF diff=astextplain 63 | 64 | # Force bash scripts to always use lf line endings 65 | *.sh text eol=lf 66 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Protocol Test Framework 2 | There are many ways to contribute to PTF. 3 | 4 | * Report bugs and help verify fixes when they are checked in. 5 | * Submit updates and improvements to the [documentation](./docs). 6 | * Contribute bug fixes. 7 | * Add new features. But firstly you should log an issue to notify the team before you spend a lot of time on it. 8 | 9 | ## CLA 10 | Contributors must sign a [Contribution License Agreement (CLA)](https://cla.microsoft.com/) before any pull requests will be considered. 11 | This is a one time job. Once you have signed a CLA for any project sponsored by Microsoft, you are good to go for all the repos sponsored by Microsoft. 12 | 13 | ## Coding Style 14 | The basic rule is following the coding style of the existing code. 15 | 16 | ## Test 17 | Every time you make changes to PTF, you should run the [unit test cases](./src/test) to avoid regression. 18 | If you add new features other than minor changes or bug fixing, you should add the relative test cases. 19 | 20 | To build test project: 21 | ``` 22 | cd ProtocoTestFramework\src\test 23 | buildtest.cmd 24 | ``` 25 | 26 | To run all the test cases: 27 | ``` 28 | runtest.cmd 29 | ``` 30 | 31 | 32 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Protocol Test Framework 2 | Copyright (c) Microsoft Corporation 3 | All rights reserved. 4 | MIT License 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Protocol Test Framework 2 | 3 | The Protocol Test Framework (PTF) is designed to support Microsoft Protocol Test Suites for both Windows and Office Protocol Interoperability testing. 4 | It implements the fundamentals to support Protocol Test Suite, including logging, checker, configuration and etc. 5 | 6 | ## Prerequisites 7 | 8 | PTF is based on .NET Core and support cross-platform. It runs on Windows, macOS and multiple distributions of Linux. 9 | You should install the software listed below based on your testing purpose, including their own dependencies. 10 | 1. [.NET Core SDK](https://dotnet.microsoft.com/download/dotnet/5.0) 11 | 12 | ## Build 13 | 14 | After you clone a copy of this repo, change to the ProtocolTestFramework directory: 15 | 16 | ``` 17 | cd ProtocolTestFramework 18 | ``` 19 | 20 | Change to src directory and build PTF: 21 | 22 | ``` 23 | cd src 24 | dotnet build --configuration Release 25 | ``` 26 | Note: 27 | 28 | For more information about how to use dotnet build please refer to :[dotnet build](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-build/) 29 | 30 | ## Samples 31 | 32 | You can find samples of how to develop a protocol test suite using PTF [here](./samples). 33 | 34 | ## Documentation 35 | 36 | * [User Guide](./docs/) describes the features of PTF, and how to use them to develop a new protocol test suite. 37 | 38 | ## Contribute 39 | 40 | You can find contributing guide [here](./CONTRIBUTING.md). 41 | 42 | ## License 43 | 44 | PTF is under the [MIT license](./LICENSE.txt). 45 | 46 | ## Microsoft Open Source Code of Conduct 47 | 48 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 49 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /docs/images/Demo.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ProtocolTestFramework/31124e75aae9d31fec9d19c10100ef9dd4a426d9/docs/images/Demo.PNG -------------------------------------------------------------------------------- /docs/images/IncludeTag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ProtocolTestFramework/31124e75aae9d31fec9d19c10100ef9dd4a426d9/docs/images/IncludeTag.png -------------------------------------------------------------------------------- /docs/images/TestExplorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ProtocolTestFramework/31124e75aae9d31fec9d19c10100ef9dd4a426d9/docs/images/TestExplorer.png -------------------------------------------------------------------------------- /docs/images/TraceScenarioConfiguration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ProtocolTestFramework/31124e75aae9d31fec9d19c10100ef9dd4a426d9/docs/images/TraceScenarioConfiguration.png -------------------------------------------------------------------------------- /pipelines/1es/PTFMainSyncToGitHub.yml: -------------------------------------------------------------------------------- 1 | name: $(date:yyyyMMdd)$(rev:.r) 2 | variables: 3 | - name: system.debug 4 | value: false 5 | - group: Access Tokens 6 | - group: Azure Account 7 | resources: 8 | repositories: 9 | - repository: 1esPipelines 10 | type: git 11 | name: 1ESPipelineTemplates/1ESPipelineTemplates 12 | ref: refs/tags/release 13 | - repository: mainPipelines 14 | type: git 15 | name: WindowsProtocolTestSuites/ProtocolTestFramework 16 | ref: AzurePipelines-main 17 | trigger: 18 | branches: 19 | include: 20 | - refs/heads/main 21 | batch: true 22 | extends: 23 | template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines 24 | parameters: 25 | pool: 26 | os: windows 27 | image: windows-2019 28 | name: Azure-Pipelines-1ESPT-ExDShared 29 | customBuildTags: 30 | - MigrationTooling-microsoft-WindowsProtocolTestSuites-53147-Tool 31 | stages: 32 | - stage: Stage 33 | jobs: 34 | - job: SyncToGithub 35 | displayName: Sync to Github 36 | steps: 37 | - template: pipelines/1es/PTFMainSyncToGitHub-steps.yml@mainPipelines 38 | 39 | -------------------------------------------------------------------------------- /pipelines/1es/azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # This Yaml Document has been converted by ESAI Yaml Pipeline Conversion Tool. 2 | # Please make sure to check all the converted content, it is your team's responsibility to make sure that the pipeline is still valid and functions as expected. 3 | # This pipeline will be extended to the OneESPT template 4 | # If you are not using the E+D shared hosted pool with windows-2022, replace the pool section with your hosted pool, os, and image name. If you are using a Linux image, you must specify an additional windows image for SDL: https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/1es-pipeline-templates/features/sdlanalysis/overview#how-to-specify-a-windows-pool-for-the-sdl-source-analysis-stage 5 | trigger: none 6 | variables: 7 | - group: Build Variables 8 | resources: 9 | repositories: 10 | - repository: 1ESPipelineTemplates 11 | type: git 12 | name: 1ESPipelineTemplates/1ESPipelineTemplates 13 | ref: refs/tags/release 14 | extends: 15 | template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates 16 | parameters: 17 | pool: 18 | name: Azure-Pipelines-1ESPT-ExDShared 19 | image: windows-2022 20 | os: windows 21 | customBuildTags: 22 | - ES365AIMigrationTooling 23 | stages: 24 | - stage: stage 25 | jobs: 26 | - job: '' 27 | displayName: Publish NuGet package 28 | workspace: 29 | clean: false 30 | timeoutInMinutes: 0 31 | steps: 32 | - task: PowerShell@2 33 | displayName: 'Build and Pack PTF' 34 | inputs: 35 | targetType: filePath 36 | filePath: ./src/build.ps1 37 | - task: CopyFiles@2 38 | displayName: 'Copy nupkg to $(Build.ArtifactStagingDirectory)' 39 | inputs: 40 | SourceFolder: src/drop 41 | Contents: '*.nupkg' 42 | TargetFolder: '$(Build.ArtifactStagingDirectory)' 43 | - task: 1ES.PublishBuildArtifacts@1 44 | displayName: 'Publish Artifact' 45 | inputs: 46 | PathtoPublish: '$(Build.ArtifactStagingDirectory)' # string. Required. Path to publish. Default: $(Build.ArtifactStagingDirectory). 47 | ArtifactName: 'drop' # string. Required. Artifact name. Default: drop. -------------------------------------------------------------------------------- /samples/XXXX_ProtocolTestSuite/XXXX_Adapter/IXXXX_Adapter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Microsoft.Protocols.TestTools; 5 | 6 | namespace Microsoft.Protocols.TestSuites.XXXX.Adapter 7 | { 8 | /// 9 | /// Defines the interface of the XXXX protocol adapter 10 | /// 11 | public interface IXXXX_Adapter: IAdapter 12 | { 13 | /// 14 | /// Sends a request to SUT 15 | /// 16 | /// Indicats IP address of SUT 17 | /// Indicates if the request is sent succesfully 18 | bool SendRequest(string SUTIPAddress); 19 | 20 | /// 21 | /// Waits for a resonse from SUT 22 | /// 23 | /// Indicates the status in the response 24 | /// Indicates the timeout in seconds when waiting for the response 25 | /// Indicates if the response is received successfully 26 | bool WaitForResponse(out int status, int timeout); 27 | } 28 | } -------------------------------------------------------------------------------- /samples/XXXX_ProtocolTestSuite/XXXX_Adapter/IXXXX_SUTControlAdapter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Microsoft.Protocols.TestTools; 5 | 6 | namespace Microsoft.Protocols.TestSuites.XXXX.Adapter 7 | { 8 | /// 9 | /// Defines the SUT control adapter 10 | /// It's used to control the SUT 11 | /// 12 | public interface IXXXX_SUTControlAdapter: IAdapter 13 | { 14 | [MethodHelp("Reset SUT to initial state. Return true for success, false for failure")] 15 | bool ResetSUT(); 16 | } 17 | } -------------------------------------------------------------------------------- /samples/XXXX_ProtocolTestSuite/XXXX_Adapter/XXXX_Adapter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Microsoft.Protocols.TestTools; 5 | 6 | namespace Microsoft.Protocols.TestSuites.XXXX.Adapter 7 | { 8 | /// 9 | /// Implements the XXXX protocol adapter 10 | /// 11 | public class XXXX_Adapter : ManagedAdapterBase, IXXXX_Adapter 12 | { 13 | /// 14 | /// Resets all the states of the adapter 15 | /// 16 | public override void Reset() 17 | { 18 | } 19 | 20 | /// 21 | /// Sends a request to SUT 22 | /// 23 | /// Indicats IP address of SUT 24 | /// Indicates if the request is sent succesfully 25 | public bool SendRequest(string SUTIPAddress) 26 | { 27 | // Add code here to construct a requst message and then send it to SUT 28 | // It's useful when the message is encrypted. 29 | return true; 30 | } 31 | 32 | /// 33 | /// Waits for a resonse from SUT 34 | /// 35 | /// Indicates the status in the response 36 | /// Indicates the timeout in seconds when waiting for the response 37 | /// Indicates if the response is received successfully 38 | public bool WaitForResponse(out int status, int timeout) 39 | { 40 | // Add code here to receive data from SUT, and parse the data to a message structure 41 | // It's useful when the message is encrypted. 42 | status = 0; 43 | 44 | // It's useful when the message is encrypted. 45 | return true; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /samples/XXXX_ProtocolTestSuite/XXXX_Adapter/XXXX_Adapter.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net8.0 4 | XXXX_Adapter 5 | Microsoft.Protocols.TestSuites.XXXX.Adapter 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | PreserveNewest 14 | 15 | 16 | -------------------------------------------------------------------------------- /samples/XXXX_ProtocolTestSuite/XXXX_Adapter/XXXX_SUTControlAdapter/ResetSUT.ps1: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Copyright (c) Microsoft. All rights reserved. 3 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 4 | ############################################################################# 5 | 6 | ###################################### 7 | # Add your own script here to reset SUT to initial state 8 | ###################################### 9 | 10 | return $TRUE -------------------------------------------------------------------------------- /samples/XXXX_ProtocolTestSuite/XXXX_ProtocolTestSuite.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30503.244 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XXXX_TestSuite", "XXXX_TestSuite\XXXX_TestSuite.csproj", "{3AE5AA9B-2A5B-442F-AF5C-B0450126590D}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XXXX_Adapter", "XXXX_Adapter\XXXX_Adapter.csproj", "{EE588106-E147-45A2-A16F-732547DB0060}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9F92954A-E424-4D9C-B1A4-5B4CA736F29A}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {3AE5AA9B-2A5B-442F-AF5C-B0450126590D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {3AE5AA9B-2A5B-442F-AF5C-B0450126590D}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {3AE5AA9B-2A5B-442F-AF5C-B0450126590D}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {3AE5AA9B-2A5B-442F-AF5C-B0450126590D}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {EE588106-E147-45A2-A16F-732547DB0060}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {EE588106-E147-45A2-A16F-732547DB0060}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {EE588106-E147-45A2-A16F-732547DB0060}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {EE588106-E147-45A2-A16F-732547DB0060}.Release|Any CPU.Build.0 = Release|Any CPU 26 | EndGlobalSection 27 | GlobalSection(SolutionProperties) = preSolution 28 | HideSolutionNode = FALSE 29 | EndGlobalSection 30 | GlobalSection(ExtensibilityGlobals) = postSolution 31 | SolutionGuid = {0BD576E4-13AE-447D-A69B-6E84E71F5AF1} 32 | EndGlobalSection 33 | EndGlobal 34 | -------------------------------------------------------------------------------- /samples/XXXX_ProtocolTestSuite/XXXX_TestSuite/XXXX_Scenario1.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using Microsoft.Protocols.TestTools; 6 | using Microsoft.Protocols.TestSuites.XXXX.Adapter; 7 | using Microsoft.VisualStudio.TestTools.UnitTesting; 8 | 9 | namespace Microsoft.Protocols.TestSuites.XXXX.TestSuite.Scenario1 10 | { 11 | /// 12 | /// Summary description for the test cases of this scenario 13 | /// 14 | [TestClass] 15 | public class XXXX_Scenario1 : TestClassBase 16 | { 17 | #region Variables 18 | // Put here fields representing adapters 19 | static IXXXX_SUTControlAdapter SUTAdapter = null; 20 | static IXXXX_Adapter protocolAdapter = null; 21 | 22 | // Other static and instance properties 23 | // ... 24 | 25 | #endregion 26 | 27 | #region Test Suite Initialization and Cleanup 28 | 29 | /// 30 | /// Use ClassInitialize to run code before running the first test in the class 31 | /// 32 | [ClassInitialize()] 33 | public static void ClassInitialize(TestContext testContext) 34 | { 35 | TestClassBase.Initialize(testContext); 36 | 37 | try 38 | { 39 | SUTAdapter = TestClassBase.BaseTestSite.GetAdapter(); 40 | protocolAdapter = TestClassBase.BaseTestSite.GetAdapter(); 41 | } 42 | catch (Exception ex) 43 | { 44 | TestClassBase.BaseTestSite.Assume.Inconclusive("ClassInitialize: Unexpected Exception - " + ex.Message); 45 | } 46 | } 47 | 48 | /// 49 | /// Use ClassCleanup to run code after all tests in a class have run 50 | /// 51 | [ClassCleanup()] 52 | public static void ClassCleanup() 53 | { 54 | TestClassBase.Cleanup(); 55 | } 56 | 57 | #endregion 58 | 59 | #region Test Case Initialization and Cleanup 60 | 61 | /// 62 | /// TestInitialize will be run before every case's execution 63 | /// 64 | protected override void TestInitialize() 65 | { 66 | try 67 | { 68 | // Do some common initialization for every case. 69 | Site.Assume.AreEqual(true, SUTAdapter.ResetSUT(), "Reset SUT to initial states"); 70 | } 71 | catch (Exception ex) 72 | { 73 | Site.Assume.Inconclusive("TestInitialize: Unexpected Exception - " + ex.Message); 74 | } 75 | } 76 | 77 | /// 78 | /// TestCleanup will be run after every case's execution 79 | /// 80 | protected override void TestCleanup() 81 | { 82 | try 83 | { 84 | // Do some common cleanup for every case. 85 | protocolAdapter.Reset(); 86 | } 87 | catch (Exception ex) 88 | { 89 | Site.Log.Add(LogEntryKind.Warning, "TestCleanup: Unexpected Exception:", ex); 90 | } 91 | } 92 | 93 | #endregion 94 | 95 | #region Test cases 96 | [TestMethod] // Indicates it's a test case 97 | [TestCategory("BVT")] // It's used to categorize the test cases 98 | [Description("The case is designed to test if the SUT could be connected")] // Describe what the test case is testing 99 | public void BVT_ConnectToSUT() 100 | { 101 | #region Case specific setup 102 | 103 | try 104 | { 105 | // Any test case specific setup logics 106 | } 107 | catch (Exception ex) 108 | { 109 | Site.Assume.Inconclusive("Unexpected Exception raised in one of custom test case setup steps: {0}", ex); 110 | } 111 | #endregion 112 | 113 | #region STEP1 Send a request to SUT 114 | Site.Log.Add(LogEntryKind.TestStep, "Step 1: Send a request to SUT"); 115 | 116 | bool ret = protocolAdapter.SendRequest(Site.Properties.Get("SUTIPAddress")); 117 | Site.Assert.IsTrue(ret, "Send request should succeed."); 118 | #endregion 119 | 120 | #region STEP2 Waiting for a response from SUT 121 | int status = 0; 122 | Site.Log.Add(LogEntryKind.TestStep, "Step 2: Wait for a response from SUT"); 123 | 124 | int timeout = int.Parse(Site.Properties.Get("SUTResponseTimeout")); 125 | ret = protocolAdapter.WaitForResponse(out status, timeout); 126 | Site.Assert.IsTrue(ret, "SUT response should be received in {0} seconds", timeout); 127 | #endregion 128 | 129 | #region Verify the status of the response 130 | // Status or other fields in the response can be checked here 131 | Site.Assert.AreEqual(0, status, "SUT should return success status in the response"); 132 | #endregion 133 | 134 | #region Case specific cleanup 135 | try 136 | { 137 | // Any test case specific clean up logics 138 | } 139 | catch (Exception ex) 140 | { 141 | Site.Log.Add(LogEntryKind.Warning, "Unexpected Exception raised in one of custom test case cleanup steps: {0}", ex); 142 | } 143 | #endregion 144 | } 145 | #endregion 146 | 147 | } 148 | 149 | } -------------------------------------------------------------------------------- /samples/XXXX_ProtocolTestSuite/XXXX_TestSuite/XXXX_TestSuite.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net8.0 4 | Library 5 | Microsoft.Protocols.TestSuites.XXXX.TestSuite 6 | false 7 | 8 | 9 | true 10 | false 11 | bin\Debug\ 12 | Debug;TRACE 13 | AllRules.ruleset 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | PreserveNewest 31 | 32 | 33 | PreserveNewest 34 | 35 | 36 | -------------------------------------------------------------------------------- /samples/XXXX_ProtocolTestSuite/XXXX_TestSuite/XXXX_TestSuite.deployment.ptfconfig: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | true,false 16 | 17 | If it is true, enable the auto-capture feature. 18 | 19 | 20 | 21 | 22 | The path to put the capture files. Old files will be overwritten. 23 | 24 | 25 | 26 | true,false 27 | 28 | If it is true, fail the test case when error happens in running network capture commands. Otherwise, ignore the error. 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | Timeout when waiting for the responses from SUT, in seconds 38 | 39 | 40 | 41 | 42 | 43 | The IP address of SUT 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /samples/XXXX_ProtocolTestSuite/XXXX_TestSuite/XXXX_TestSuite.ptfconfig: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/PTFTestLogger/PTFTestLogger.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net6.0;net7.0;net8.0 4 | Library 5 | Microsoft 6 | Microsoft.Protocols.TestTools.PTFTestLogger 7 | Html logger for PTF 8 | Microsoft.Protocols.TestTools.PTFTestLogger 9 | false 10 | 11 | 12 | 13 | 14 | 15 | 16 | True 17 | True 18 | Resources.resx 19 | 20 | 21 | 22 | 23 | ResXFileCodeGenerator 24 | Resources.Designer.cs 25 | Designer 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/PTFTestLogger/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Microsoft.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// CSS file for test case log page 65 | /// 66 | internal static string casepage { 67 | get { 68 | return ResourceManager.GetString("casepage", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized string similar to // Copyright (c) Microsoft. All rights reserved. 74 | ///// Licensed under the MIT license. See LICENSE file in the project root for full license information. 75 | /// 76 | ///var filter = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH8AAAAXCAYAAAAiGpAkAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAADjSURBVGhD7doxCoQwEAXQiYm5lhbiXsLDeBf7tJZeSGzcTjHLhCwry8KmnvkPJHEsPx9RYvb9GQlUqvIKCpl1XeOyLHRdVx6BZMYY6rqO6tqTmaYpDsOQH4EGIQTq+wdV3vs8Ai3O80wr3vmKIXzFEL5iCF8xhC9A27bpE+5+8ewfhC/AOI559/Fr9g3hC8Atb5om31Hao/mK3 [rest of string was truncated]";. 77 | /// 78 | internal static string functions { 79 | get { 80 | return ResourceManager.GetString("functions", resourceCulture); 81 | } 82 | } 83 | 84 | /// 85 | /// Looks up a localized string similar to <!DOCTYPE html> 86 | ///<html> 87 | ///<head> 88 | /// 89 | ///<style type="text/css"> 90 | ///div#left_sidebar {width:29%;float:left;overflow:auto;overflow:scroll;overflow-x:hidden} 91 | ///div#back_to_summary {width:68%;float:left;overflow:auto;} 92 | ///div#right_sidebar_summary {width:68%;float:left;overflow:auto;margin-left:-2px} 93 | ///div#right_sidebar_case {width:68%;float:left;overflow:auto;margin-left:-2px} 94 | ///h1 {margin-bottom:0;} 95 | ///ul {margin:0;} 96 | ///li {list-style:none;} 97 | /// 98 | ///body{ 99 | /// font-family:Arial,Verdana,Sans-serif; 100 | /// background-color: rgb(243,2 [rest of string was truncated]";. 101 | /// 102 | internal static string index { 103 | get { 104 | return ResourceManager.GetString("index", resourceCulture); 105 | } 106 | } 107 | 108 | /// 109 | /// Looks up a localized string similar to <!DOCTYPE html> 110 | /// 111 | ///<html> 112 | ///<head> 113 | /// <meta charset="utf-8" /> 114 | /// <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> 115 | /// <title></title> 116 | /// <style type="text/css"> 117 | ///h1 {margin-bottom:0;} 118 | ///ul {margin:0;} 119 | /// 120 | ///body{ 121 | /// font-family:Arial,Verdana,Sans-serif; 122 | /// background-color: rgb(243,243,244); 123 | ///} 124 | ///h1.title{ 125 | /// color: #1382CE; 126 | /// font-family:Arial,Verdana,Sans-serif; 127 | /// font-weight: bold; 128 | /// font-size:1.25rem; 129 | ///} 130 | /// 131 | ///div.frame { 132 | /// color:white; 133 | /// border-style: groove; 134 | /// font-weight [rest of string was truncated]";. 135 | /// 136 | internal static string testcase { 137 | get { 138 | return ResourceManager.GetString("testcase", resourceCulture); 139 | } 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/PTFTestLogger/Resources/casepage.css: -------------------------------------------------------------------------------- 1 | h1 { 2 | margin-bottom: 0; 3 | } 4 | 5 | ul { 6 | margin: 0; 7 | } 8 | 9 | body { 10 | font-family: Arial, Verdana, Sans-serif; 11 | background-color: rgb(243, 243, 244); 12 | } 13 | 14 | h1.title { 15 | color: #1382ce; 16 | font-family: Arial, Verdana, Sans-serif; 17 | font-weight: bold; 18 | font-size: 1.25rem; 19 | } 20 | 21 | div.frame { 22 | color: white; 23 | border-style: groove; 24 | font-weight: bold; 25 | font-size: 110%; 26 | filter: alpha(opacity=30); 27 | border: none; 28 | padding: 0.3125rem 0.3125rem 0.3125rem 0.3125rem; 29 | background-color: #1382ce; 30 | } 31 | 32 | div.filter { 33 | background-color: White; 34 | border: 0.0625rem solid; 35 | border-color: grey; 36 | font-size: 0.625rem; 37 | position: absolute; 38 | left: 1.25rem; 39 | margin-left: 4.0625rem; 40 | padding-right: 0.3125rem; 41 | padding-bottom: 0.3125rem; 42 | } 43 | 44 | div.filterframe { 45 | font-size: 0.75rem; 46 | font-weight: bold; 47 | margin-left: 1.25rem; 48 | } 49 | 50 | div { 51 | font-size: 90%; 52 | } 53 | 54 | div.sub { 55 | margin-left: 1.25rem; 56 | } 57 | 58 | img.small { 59 | vertical-align: 0.0625rem; 60 | margin-right: 0.375rem; 61 | } 62 | 63 | a { 64 | cursor: pointer; 65 | } 66 | -------------------------------------------------------------------------------- /src/PTFTestLogger/Resources/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 180 | 181 | 182 | 198 | 199 | 204 | 205 | 208 | 209 | 210 | 211 | 212 | -------------------------------------------------------------------------------- /src/PTFTestLogger/Resources/testcase.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

14 |

15 |
16 |
17 | 18 | 19 | 29 | 30 | -------------------------------------------------------------------------------- /src/ProtocolTestFramework.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio Version 16 3 | VisualStudioVersion = 16.0.30804.86 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestFramework", "TestFramework\TestFramework.csproj", "{88CEBF69-2B62-4449-8B36-9B766BC5D418}" 6 | EndProject 7 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "UnitTest\UnitTest.csproj", "{EC877C6C-D944-42E9-8A37-739A27211142}" 8 | EndProject 9 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestFramework.AdapterConsole", "TestFramework.AdapterConsole\TestFramework.AdapterConsole.csproj", "{C8DCFC5E-7F5F-4E9E-B059-F5079EA8B23B}" 10 | EndProject 11 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B685E07E-928E-4CFC-8B7D-2556302A135D}" 12 | EndProject 13 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PTFTestLogger", "PTFTestLogger\PTFTestLogger.csproj", "{7953DF59-C900-433D-97A1-F86EC6CCDDCF}" 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Debug|Any CPU = Debug|Any CPU 18 | Release|Any CPU = Release|Any CPU 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {88CEBF69-2B62-4449-8B36-9B766BC5D418}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {88CEBF69-2B62-4449-8B36-9B766BC5D418}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {88CEBF69-2B62-4449-8B36-9B766BC5D418}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {88CEBF69-2B62-4449-8B36-9B766BC5D418}.Release|Any CPU.Build.0 = Release|Any CPU 25 | {EC877C6C-D944-42E9-8A37-739A27211142}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {EC877C6C-D944-42E9-8A37-739A27211142}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {EC877C6C-D944-42E9-8A37-739A27211142}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {EC877C6C-D944-42E9-8A37-739A27211142}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {C8DCFC5E-7F5F-4E9E-B059-F5079EA8B23B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 30 | {C8DCFC5E-7F5F-4E9E-B059-F5079EA8B23B}.Debug|Any CPU.Build.0 = Debug|Any CPU 31 | {C8DCFC5E-7F5F-4E9E-B059-F5079EA8B23B}.Release|Any CPU.ActiveCfg = Release|Any CPU 32 | {C8DCFC5E-7F5F-4E9E-B059-F5079EA8B23B}.Release|Any CPU.Build.0 = Release|Any CPU 33 | {7953DF59-C900-433D-97A1-F86EC6CCDDCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 34 | {7953DF59-C900-433D-97A1-F86EC6CCDDCF}.Debug|Any CPU.Build.0 = Debug|Any CPU 35 | {7953DF59-C900-433D-97A1-F86EC6CCDDCF}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {7953DF59-C900-433D-97A1-F86EC6CCDDCF}.Release|Any CPU.Build.0 = Release|Any CPU 37 | EndGlobalSection 38 | GlobalSection(SolutionProperties) = preSolution 39 | HideSolutionNode = FALSE 40 | EndGlobalSection 41 | GlobalSection(ExtensibilityGlobals) = postSolution 42 | SolutionGuid = {031D1F97-663A-43F8-BB3D-4767AEFE6F5E} 43 | EndGlobalSection 44 | EndGlobal 45 | -------------------------------------------------------------------------------- /src/SharedAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Reflection; 5 | 6 | [assembly: AssemblyCompany("Microsoft")] 7 | [assembly: AssemblyVersion("2.5.0")] 8 | [assembly: AssemblyFileVersion("2.5.0.0")] 9 | [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] -------------------------------------------------------------------------------- /src/TestFramework.AdapterConsole/KeyHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Microsoft.Protocols.TestTools.AdapterConsole 9 | { 10 | internal class KeyHandler 11 | { 12 | private ConsoleKeyInfo _keyInfo; 13 | private Dictionary _keyActions; 14 | private StringBuilder _text; 15 | 16 | internal KeyHandler() 17 | { 18 | _keyActions = new Dictionary(); 19 | _text = new StringBuilder(); 20 | } 21 | 22 | private string BuildKeyInput() 23 | { 24 | return (_keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift) ? 25 | _keyInfo.Key.ToString() : _keyInfo.Modifiers.ToString() + _keyInfo.Key.ToString(); 26 | } 27 | 28 | private void WriteContent() => WriteContent(_keyInfo.KeyChar); 29 | 30 | private void WriteContent(char c) 31 | { 32 | _text.Append(c); 33 | Console.Write(c.ToString()); 34 | } 35 | 36 | public string Text 37 | { 38 | get 39 | { 40 | return _text.ToString(); 41 | } 42 | } 43 | 44 | public void Handle(ConsoleKeyInfo keyInfo) 45 | { 46 | _keyInfo = keyInfo; 47 | 48 | Action action; 49 | _keyActions.TryGetValue(BuildKeyInput(), out action); 50 | action = action ?? WriteContent; 51 | action.Invoke(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/TestFramework.AdapterConsole/ParameterInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Microsoft.Protocols.TestTools.AdapterConsole 7 | { 8 | public class ParaCommandInfo 9 | { 10 | public string Title { get; set; } 11 | 12 | public string ParameterName { get; set; } 13 | 14 | public int ParameterIndex { get; set; } 15 | 16 | public string Content { get; set; } 17 | 18 | public bool IsExecute { get; set; } 19 | 20 | public string Type { get; set; } 21 | 22 | public object Value { get; set; } 23 | } 24 | 25 | public class ArgDetail 26 | { 27 | public string HelpMsg { get; set; } 28 | 29 | public ParaCommandInfo ReturnParam { get; set; } 30 | 31 | public List OutParams { get; set; } 32 | 33 | public string OutFilePath { get; set; } 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/TestFramework.AdapterConsole/ProcessResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.Protocols.TestTools.AdapterConsole 8 | { 9 | [Serializable] 10 | public class ProcessResult 11 | { 12 | public string ReturnValue { get; set; } 13 | 14 | public Dictionary OutArgValues { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/TestFramework.AdapterConsole/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.IO; 6 | using System.Text; 7 | using System.Text.Json; 8 | 9 | namespace Microsoft.Protocols.TestTools.AdapterConsole 10 | { 11 | class Program 12 | { 13 | static int Main(string[] args) 14 | { 15 | if (args.Length > 0) 16 | { 17 | Console.ForegroundColor = ConsoleColor.Green; 18 | ProcessResult result = new ProcessResult(); 19 | var arg = JsonSerializer.Deserialize(args[0]); 20 | ConsoleHelper.WriteToConsole(string.Empty); //write empty line 21 | ConsoleHelper.WriteToConsole(arg.HelpMsg); 22 | 23 | if (arg.ReturnParam != null) 24 | { 25 | result.ReturnValue =""+ ConsoleHelper.GetYesNoFromConsole(arg.ReturnParam.Title); 26 | } 27 | 28 | if (arg.OutParams != null && arg.OutParams.Count > 0) 29 | { 30 | result.OutArgValues = new System.Collections.Generic.Dictionary(); 31 | foreach (var outarg in arg.OutParams) 32 | { 33 | var outValue = "" + ConsoleHelper.GetValueFromConsole($"Please enter {outarg.Title}", Type.GetType(outarg.Type)); 34 | if (!result.OutArgValues.ContainsKey(outarg.ParameterName)) 35 | { 36 | result.OutArgValues.Add(outarg.ParameterName, outValue); 37 | } 38 | else 39 | { 40 | result.OutArgValues[outarg.ParameterName] = outValue; 41 | } 42 | } 43 | } 44 | 45 | string resultContent = JsonSerializer.Serialize(result); 46 | File.WriteAllText(arg.OutFilePath, resultContent, Encoding.UTF8); 47 | } 48 | else 49 | { 50 | return -1; 51 | } 52 | 53 | return 0; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/TestFramework.AdapterConsole/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "TestFramework.AdapterConsole": { 4 | "commandName": "Project" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /src/TestFramework.AdapterConsole/TestFramework.AdapterConsole.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net6.0;net7.0;net8.0 6 | Microsoft.Protocols.TestTools.AdapterConsole 7 | Microsoft.Protocols.TestTools.AdapterConsole 8 | Interactive console adapter 9 | Microsoft Protocol Test Framework Interactive Console Adapter 10 | false 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Adapters/AdapterProxyHelpers.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using System.Reflection; 8 | 9 | namespace Microsoft.Protocols.TestTools 10 | { 11 | internal static class AdapterProxyHelpers 12 | { 13 | /// 14 | /// Gets the help attribute content for the calling method. 15 | /// 16 | /// The method from the adapter proxy. 17 | /// The help message content. 18 | internal static string GetHelpMessage(MethodInfo targetMethod) 19 | { 20 | if (targetMethod == null) 21 | { 22 | throw new ArgumentNullException("targetMethod"); 23 | } 24 | // Find the MethodHelp attribute and the corresponding message. 25 | object[] attrs = targetMethod.GetCustomAttributes(typeof(MethodHelpAttribute), false); 26 | if (attrs.Length > 0) 27 | { 28 | return ((MethodHelpAttribute)attrs[0]).HelpMessage; 29 | } 30 | return String.Empty; 31 | } 32 | 33 | /// 34 | /// Gets the timeout attribute value for the calling method. 35 | /// 36 | /// The method from the adapter proxy. 37 | /// Default timeout. 38 | /// timeout value. 39 | internal static int GetTimeout(MethodInfo targetMethod, int defaultValue) 40 | { 41 | if (targetMethod == null) 42 | { 43 | throw new ArgumentNullException("targetMethod"); 44 | } 45 | // Find the MethodHelp attribute and the corresponding message. 46 | object[] attrs = targetMethod.GetCustomAttributes(typeof(InvokeTimeoutAttribute), false); 47 | if (attrs.Length > 0) 48 | { 49 | return ((InvokeTimeoutAttribute)attrs[0]).InvokeTimeoutValue; 50 | } 51 | return defaultValue; 52 | } 53 | 54 | /// 55 | /// Parses the result and convert it to the corresponding type. 56 | /// 57 | /// The type of the result which should be converted to. 58 | /// A string containing the name or value to convert. 59 | /// 60 | internal static object ParseResult(Type type, string result) 61 | { 62 | if (result == null) 63 | { 64 | // Empty string should be accepted by 'Parse', hence only check null reference. 65 | throw new ArgumentNullException("result"); 66 | } 67 | 68 | // Convert to non-ref types 69 | if (type.IsByRef) 70 | { 71 | type = type.GetElementType(); 72 | } 73 | 74 | MethodInfo mi; 75 | // Specially processing String type. 76 | if (type == typeof(String)) 77 | { 78 | // Ingore String type. 79 | return result; 80 | } 81 | // Specially processing Enum type. 82 | else if (type.IsAssignableFrom(typeof(Enum)) || type.IsEnum) 83 | { 84 | try 85 | { 86 | return Enum.Parse(type, result, true); 87 | } 88 | catch (ArgumentException) 89 | { 90 | throw new FormatException(); 91 | } 92 | } 93 | else 94 | { 95 | // Check if T has a 'Parse' method. 96 | try 97 | { 98 | mi = type.GetMethod( 99 | "Parse", 100 | BindingFlags.Static | BindingFlags.Public, 101 | null, 102 | new Type[] { typeof(string) }, 103 | new ParameterModifier[0] 104 | ); 105 | } 106 | catch (AmbiguousMatchException e) 107 | { 108 | throw new FormatException( 109 | String.Format("More than one 'Parse' method is found in {0}.", type), e 110 | ); 111 | } 112 | if (mi == null) 113 | { 114 | throw new FormatException( 115 | String.Format( 116 | "Can not parse the result, " + 117 | "due to the type {0} doesn't contain a method 'public static {0} Parse (String)'.", type) 118 | ); 119 | } 120 | 121 | // Invoke and get the result. 122 | object res = null; 123 | try 124 | { 125 | res = mi.Invoke(null, new object[] { result }); 126 | } 127 | catch (TargetInvocationException e) 128 | { 129 | if (e.InnerException != null && e.InnerException is FormatException) 130 | { 131 | throw e.InnerException; 132 | } 133 | else 134 | { 135 | throw; 136 | } 137 | } 138 | 139 | return res; 140 | } 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Adapters/DefaultValueAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Microsoft.Protocols.TestTools 9 | { 10 | /// 11 | /// Provides a default return value attribute used by adapter methods. 12 | /// 13 | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter, Inherited = false, AllowMultiple = false)] 14 | public sealed class DefaultValueAttribute : Attribute 15 | { 16 | private readonly string defaultValue; 17 | /// 18 | /// Disables the default constructor. 19 | /// 20 | private DefaultValueAttribute() 21 | { 22 | } 23 | 24 | /// 25 | /// Initializes the attribute with specified default value. 26 | /// 27 | /// The default value string. 28 | public DefaultValueAttribute(string defaultValue) 29 | { 30 | this.defaultValue = defaultValue; 31 | } 32 | 33 | /// 34 | /// Gets the content of the helper message. 35 | /// 36 | public string DefaultValue 37 | { 38 | get 39 | { 40 | return this.defaultValue; 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Adapters/Interactive/InteractiveAdapterProxy.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Reflection; 6 | using System.Runtime.InteropServices; 7 | 8 | namespace Microsoft.Protocols.TestTools 9 | { 10 | /// 11 | /// 12 | /// 13 | public class InteractiveAdapterProxy : AdapterProxyBase 14 | { 15 | private string scriptDirectory; 16 | 17 | /// 18 | /// Create an instance of the powershell adapter. 19 | /// 20 | /// The type of the adapter. 21 | /// The folder containing the script files. 22 | /// The type of the adapter. 23 | /// The powershell adapter 24 | public static T Wrap(Type typeToProxy) where T : IAdapter 25 | { 26 | object proxy = Create(); 27 | InteractiveAdapterProxy self = (InteractiveAdapterProxy)proxy; 28 | 29 | AdapterProxyBase.SetParameters(self, typeToProxy); 30 | //self.scriptDirectory = scriptDirectory.Replace("\\", "/"); 31 | 32 | return (T)proxy; 33 | } 34 | 35 | /// 36 | /// 37 | /// 38 | /// 39 | /// 40 | /// 41 | protected override object ExecuteMethod(MethodInfo methodCall, object[] args) 42 | { 43 | int retVal = 0; 44 | 45 | // Check if this is a method from IAdapter. Any IAdapter methods should be ignored. 46 | if (!AdapterType.IsAdapterTypeFullName(methodCall.DeclaringType.FullName) 47 | && (methodCall.DeclaringType.FullName != typeof(IDisposable).FullName) 48 | ) 49 | { 50 | TestSite.Log.Add(LogEntryKind.EnterAdapter, 51 | "Managed adapter: {0}, method: {1}", 52 | ProxyType.Name, 53 | methodCall.Name); 54 | 55 | try 56 | { 57 | string msg = "Failed"; 58 | using (InteractiveAdapterConsole consoleAdapter = new InteractiveAdapterConsole(methodCall, TestSite.Properties, args)) 59 | { 60 | retVal = consoleAdapter.ProcessArguments(); 61 | if (retVal == 0) // Abort case. 62 | { 63 | TestSite.Log.Add(LogEntryKind.Warning, "Case manually aborted."); 64 | TestSite.Assert.Fail(msg); 65 | } 66 | } 67 | } 68 | catch (Exception ex) 69 | { 70 | TestSite.Log.Add(LogEntryKind.Debug, ex.ToString()); 71 | throw; 72 | } 73 | finally 74 | { 75 | TestSite.Log.Add(LogEntryKind.ExitAdapter, 76 | "PowerShell adapter: {0}, method: {1}", 77 | ProxyType.Name, 78 | methodCall.Name); 79 | } 80 | } 81 | 82 | return retVal; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Adapters/InvokeTimeoutAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Protocols.TestTools 7 | { 8 | [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] 9 | public class InvokeTimeoutAttribute: Attribute 10 | { 11 | private readonly int defaultValue; 12 | /// 13 | /// Disables the default constructor. 14 | /// 15 | private InvokeTimeoutAttribute() 16 | { 17 | } 18 | 19 | /// 20 | /// Initializes the attribute with specified default value. 21 | /// 22 | /// The default timeout minutes. 23 | public InvokeTimeoutAttribute(int defaultValue) 24 | { 25 | this.defaultValue = defaultValue; 26 | } 27 | 28 | /// 29 | /// Gets the value of InvokeTimeout 30 | /// 31 | public int InvokeTimeoutValue 32 | { 33 | get 34 | { 35 | return this.defaultValue; 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Adapters/MethodHelpAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Microsoft.Protocols.TestTools 9 | { 10 | /// 11 | /// Provides a helper attribute used by adapter methods. 12 | /// 13 | [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] 14 | public sealed class MethodHelpAttribute : Attribute 15 | { 16 | readonly string helpMessage; 17 | 18 | /// 19 | /// Disables the default constructor. 20 | /// 21 | private MethodHelpAttribute() 22 | { 23 | } 24 | 25 | /// 26 | /// Initializes the attribute with specified message. 27 | /// 28 | /// The helper message string. 29 | public MethodHelpAttribute(string helpMessage) 30 | { 31 | this.helpMessage = helpMessage; 32 | } 33 | 34 | /// 35 | /// Gets the content of the helper message. 36 | /// 37 | public string HelpMessage 38 | { 39 | get 40 | { 41 | return this.helpMessage; 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Attributes/ProtocolTestCleanupAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Protocols.TestTools 7 | { 8 | /// 9 | /// An internal attribute to callback test cleanup action through PTF. 10 | /// 11 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] 12 | sealed public class ProtocolTestCleanupAttribute : Attribute 13 | { 14 | /// 15 | /// Constructor 16 | /// 17 | public ProtocolTestCleanupAttribute() 18 | { } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Attributes/ProtocolTestInitializeAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Protocols.TestTools 7 | { 8 | /// 9 | /// An internal attribute to callback test initialize action through PTF. 10 | /// 11 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] 12 | sealed public class ProtocolTestInitializeAttribute : Attribute 13 | { 14 | /// 15 | /// Constructor 16 | /// 17 | public ProtocolTestInitializeAttribute() 18 | { } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/TestFramework/Core/ConfigurationDataProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.IO; 6 | using System.Xml; 7 | using System.Xml.XPath; 8 | using System.Reflection; 9 | using System.Collections.Generic; 10 | using System.Collections.Specialized; 11 | using System.Xml.Schema; 12 | using System.Text; 13 | using System.Collections; 14 | using Microsoft.Win32; 15 | using System.Collections.ObjectModel; 16 | using System.Runtime.InteropServices; 17 | 18 | namespace Microsoft.Protocols.TestTools 19 | { 20 | /// 21 | /// Configuration data provider 22 | /// 23 | public static class ConfigurationDataProvider 24 | { 25 | private static ConfigurationReader reader; 26 | 27 | /// 28 | /// Gets the configuration data. 29 | /// 30 | /// Ptfconfig directory 31 | /// Test suite name 32 | /// The configuration data 33 | public static IConfigurationData GetConfigurationData(string ptfconfigDirectory, string testSuiteName) 34 | { 35 | // Get fullnames of PTF config files. 36 | 37 | string[] configFiles = GetConfigFileShortNames(testSuiteName); 38 | string[] configFileFullnames = new string[configFiles.Length]; 39 | 40 | 41 | for (int i = 0; i < configFiles.Length; i++) 42 | { 43 | configFileFullnames[i] = GetTestSuitePtfconfigFileName(ptfconfigDirectory, configFiles[i]); 44 | } 45 | 46 | //.ptfconfig is required. 47 | if (!File.Exists(Path.Combine(ptfconfigDirectory, String.Format("{0}.ptfconfig", testSuiteName)))) 48 | { 49 | throw new InvalidOperationException( 50 | String.Format("Cannot find {0}. Please make sure it is placed in {1}.", 51 | testSuiteName + ".ptfconfig", ptfconfigDirectory)); 52 | } 53 | 54 | reader = new ConfigurationReader(configFileFullnames); 55 | 56 | return reader; 57 | } 58 | 59 | /// 60 | /// Gets config file short names based on the given test suite name. 61 | /// 62 | /// The test suite name 63 | /// string array which contrains the names of configuration files 64 | private static string[] GetConfigFileShortNames(string testSuiteName) 65 | { 66 | return new string[] 67 | { 68 | testSuiteName + ".ptfconfig", 69 | testSuiteName + ".deployment.ptfconfig" 70 | }; 71 | } 72 | 73 | /// 74 | /// Gets the full path name of the ptfconfig file name. 75 | /// 76 | /// The path of ptfconfig directory. 77 | /// The configuration file short name. 78 | /// The full path name of the ptfconfig file name. 79 | private static string GetTestSuitePtfconfigFileName(string ptfconfigDirectory, string filename) 80 | { 81 | string[] files = null; 82 | 83 | try 84 | { 85 | files = System.IO.Directory.GetFiles(ptfconfigDirectory, filename, SearchOption.TopDirectoryOnly); 86 | } 87 | catch (System.UnauthorizedAccessException) { } 88 | catch (System.ArgumentNullException) { } 89 | catch (System.IO.IOException) { } 90 | catch (System.ArgumentException) { } 91 | 92 | if (files != null && files.Length > 0) 93 | return files[0]; 94 | else 95 | return null; 96 | } 97 | 98 | /// 99 | /// Tries to get the check the configuration data. 100 | /// 101 | /// check configuration type. 102 | /// check configuration data. 103 | /// Returns true if successfully get the check configuration data, otherwise return false. 104 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 105 | public static bool TryGetCheckerConfig(out T checkConfig) 106 | { 107 | checkConfig = default(T); 108 | if (null != reader) 109 | { 110 | object value = reader; 111 | try 112 | { 113 | checkConfig = (T)value; 114 | return true; 115 | } 116 | catch 117 | { 118 | //ignore the cast exception and return false. 119 | } 120 | } 121 | return false; 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/TestFramework/Core/ConfigurationPropertyName.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Microsoft.Protocols.TestTools 9 | { 10 | /// 11 | /// A static class which contains the XML node names in the PTF configuration files. 12 | /// 13 | public static class ConfigurationPropertyName 14 | { 15 | /// 16 | /// Server name 17 | /// 18 | public const string ServerName = "ServerComputerName"; 19 | 20 | /// 21 | /// Feature name 22 | /// 23 | public const string ProtocolName = "FeatureName"; 24 | 25 | /// 26 | /// Version 27 | /// 28 | public const string ProtocolVersion = "Version"; 29 | 30 | /// 31 | /// Test suite name 32 | /// 33 | public const string TestName = "TestName"; 34 | 35 | /// 36 | /// Regex filter for preventing throwing exception from the failure of Assert 37 | /// 38 | public const string ExceptionFilter = "ExceptionFilter"; 39 | 40 | /// 41 | /// Regex filter to judge the result together with condition 42 | /// 43 | public const string BypassFilter = "BypassFilter"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/TestFramework/Core/IAdapter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Microsoft.Protocols.TestTools 9 | { 10 | 11 | /// 12 | /// An interface that every adapter must implement. 13 | /// 14 | public interface IAdapter : IDisposable 15 | { 16 | /// 17 | /// Gets the test site associated with this adapter. 18 | /// 19 | ITestSite Site { get; } 20 | 21 | /// 22 | /// Initializes the current adapter instance and associates with a test site. 23 | /// 24 | /// 25 | /// This method is called automatically by . User needs not call it directly. 26 | /// 27 | /// The test site instance associated with the current adapter. 28 | void Initialize(ITestSite testSite); 29 | 30 | /// 31 | /// This method is called before each test case runs. User does not need to call it directly. 32 | /// 33 | void Reset(); 34 | } 35 | 36 | /// 37 | /// A class which contains static methods used to determine adapter types. 38 | /// 39 | public sealed class AdapterType 40 | { 41 | /// 42 | /// The adapter base type's full name. 43 | /// 44 | private static string fullName = typeof(IAdapter).FullName; 45 | 46 | /// 47 | /// Disables the default constructor. 48 | /// 49 | private AdapterType() 50 | { 51 | } 52 | 53 | /// 54 | /// Gets the full name of adapter base type. 55 | /// 56 | public static string AdapterTypeFullName 57 | { 58 | get { return fullName; } 59 | } 60 | 61 | /// 62 | /// Gets a bool value which indicates whether the specified string is the full name of the adapter base type . 63 | /// 64 | /// The full name of the type. 65 | /// true if it equals the adapter base type's full name; otherwise, false. 66 | public static bool IsAdapterTypeFullName(string typeFullName) 67 | { 68 | return (fullName == typeFullName); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/TestFramework/Core/ICheckerConfig.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Microsoft.Protocols.TestTools 9 | { 10 | /// 11 | /// The checker configuration 12 | /// 13 | public interface ICheckerConfig 14 | { 15 | /// 16 | /// The number of assert failures need to be bypassed. 17 | /// 18 | int AssertFailuresBeforeThrowException {get;} 19 | 20 | /// 21 | /// The maximum failure messages need to be displayed. 22 | /// 23 | int MaxFailuresToDisplayPerTestCase { get; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/TestFramework/Core/IProtocolTestContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Microsoft.Protocols.TestTools 9 | { 10 | /// 11 | /// Test outcome. 12 | /// 13 | public enum PtfTestOutcome 14 | { 15 | /// 16 | /// Test case failed 17 | /// 18 | Failed = 0, 19 | 20 | /// 21 | /// Test case status is inconclusive 22 | /// 23 | Inconclusive, 24 | 25 | /// 26 | /// Test case passed 27 | /// 28 | Passed, 29 | 30 | /// 31 | /// Test case is in progress 32 | /// 33 | InProgress, 34 | 35 | /// 36 | /// Test case encounters an error 37 | /// 38 | Error, 39 | 40 | /// 41 | /// Test case is time out 42 | /// 43 | Timeout, 44 | 45 | /// 46 | /// Test case is aborted 47 | /// 48 | Aborted, 49 | 50 | /// 51 | /// Test case status is unknown 52 | /// 53 | Unknown, 54 | } 55 | 56 | /// 57 | /// Internal use only. 58 | /// 59 | public interface IProtocolTestContext 60 | { 61 | /// 62 | /// Gets test assembly directory. 63 | /// 64 | string TestAssemblyDir { get; } 65 | 66 | /// 67 | /// Gets ptfconfig directory. 68 | /// 69 | string PtfconfigDir { get; } 70 | 71 | /// 72 | /// Gets test case run outcome. 73 | /// 74 | PtfTestOutcome TestOutcome { get; } 75 | 76 | /// 77 | /// Gets running test method name. 78 | /// 79 | string TestMethodName { get; } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/TestFramework/Core/IProtocolTestNotify.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Microsoft.Protocols.TestTools 9 | { 10 | /// 11 | /// An interface which provides methods for protocol tests' initialization and cleaning up. 12 | /// 13 | public interface IProtocolTestNotify 14 | { 15 | /// 16 | /// Should be called before each test method runs. 17 | /// 18 | /// Instance of the test class 19 | /// Test case name 20 | /// Test outcome 21 | /// Handler provided to process the assert exception 22 | void OnTestStarted(object testClass, string testName, PtfTestOutcome testOutcome, AssertExceptionHandler exceptionHandler); 23 | 24 | /// 25 | /// Should be called after each test method runs. 26 | /// 27 | /// Instance of the test class 28 | /// Test case name 29 | /// Test outcome 30 | /// Handler provided to process the assert exception 31 | void OnTestFinished(object testClass, string testName, PtfTestOutcome testOutcome, AssertExceptionHandler exceptionHandler); 32 | } 33 | 34 | /// 35 | /// A delegate which is used by and 36 | /// 37 | /// Exception need to be handled 38 | /// PtfTestOutcome corresponding to the assert exception 39 | public delegate PtfTestOutcome AssertExceptionHandler(Exception exception); 40 | } 41 | -------------------------------------------------------------------------------- /src/TestFramework/Core/ITestLog.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Protocols.TestTools 5 | { 6 | /// 7 | /// Interface of TestLog 8 | /// 9 | public interface ITestLog 10 | { 11 | /// 12 | /// BeginTest 13 | /// 14 | /// The test name 15 | void BeginTest(string name); 16 | 17 | /// 18 | /// EndTest 19 | /// 20 | void EndTest(); 21 | 22 | /// 23 | /// Checks condition together with description to by-pass assertion failure. 24 | /// 25 | /// A bool condition 26 | /// Description message for Assert 27 | /// false if and only if condition is false and description is not by-passed. 28 | bool IsTrue(bool condition, string description); 29 | 30 | /// 31 | /// Assume 32 | /// 33 | /// A bool condition 34 | /// Description message for Assume 35 | void Assume(bool condition, string description); 36 | 37 | /// 38 | /// Assert 39 | /// 40 | /// A bool condition 41 | /// Description message for Assert 42 | void Assert(bool condition, string description); 43 | 44 | /// 45 | /// Comment 46 | /// 47 | /// Description message for a comment in log 48 | void Comment(string description); 49 | 50 | /// 51 | /// Checkpoint 52 | /// 53 | /// Description message for a check point in log 54 | void Checkpoint(string description); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Logging/ApplicationLog.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using System.Collections.Specialized; 8 | using System.ComponentModel; 9 | using System.Diagnostics.CodeAnalysis; 10 | using System.IO; 11 | using System.Diagnostics; 12 | 13 | 14 | namespace Microsoft.Protocols.TestTools.Logging 15 | { 16 | /// 17 | /// This class contains supporting PTF application log. 18 | /// 19 | internal static class ApplicationLog 20 | { 21 | //Output file stream name 22 | private const string logFileName = "PTFApplicationLog.txt"; 23 | 24 | //Output file stream 25 | private static TextWriterTraceListener textListener; 26 | 27 | //Log message format 28 | private const string timeStampFormat = "{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}.{6:D3}"; 29 | 30 | /// 31 | /// Static Constructor for ApplicationLog. 32 | /// 33 | /// Failure on application log should not prevent the PTF from executing 34 | [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 35 | static ApplicationLog() 36 | { 37 | try 38 | { 39 | //Initialize trace listener 40 | FileStream logFileStream = new FileStream(logFileName, 41 | FileMode.Append, 42 | FileAccess.Write, 43 | FileShare.ReadWrite); 44 | 45 | if (logFileStream != null) 46 | { 47 | textListener = new TextWriterTraceListener(logFileStream); 48 | Trace.Listeners.Clear(); 49 | Trace.Listeners.Add(textListener); 50 | } 51 | } 52 | catch(Exception) 53 | { 54 | //We shouldn't catch general exception, but failure on application 55 | //log should not prevent the PTF from executing. 56 | } 57 | 58 | } 59 | 60 | /// 61 | /// Write a message to Trace listeners 62 | /// 63 | /// The message to write to the log file 64 | /// Failure on application log should not prevent the PTF from executing 65 | [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 66 | internal static void TraceLog(string message) 67 | { 68 | //format the message 69 | DateTime timeStamp = DateTime.Now; 70 | string timeStampInfo = string.Format(timeStampFormat, 71 | timeStamp.Year, 72 | timeStamp.Month, 73 | timeStamp.Day, 74 | timeStamp.Hour, 75 | timeStamp.Minute, 76 | timeStamp.Second, 77 | timeStamp.Millisecond); 78 | 79 | string logMessage = string.Format("[PTF Internal Trace Log][{0}] {1}", 80 | timeStampInfo, 81 | message); 82 | 83 | //Write the message into trace listeners 84 | try 85 | { 86 | Trace.WriteLine(logMessage); 87 | 88 | if (textListener != null) 89 | { 90 | textListener.Flush(); 91 | } 92 | } 93 | catch (Exception) 94 | { 95 | //We shouldn't catch general exception, but application on internal 96 | //log should not prevent the PTF from executing. 97 | } 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Logging/LogInformationName.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Microsoft.Protocols.TestTools.Logging 9 | { 10 | internal static class LogInformationName 11 | { 12 | internal const string Message = "Message"; 13 | internal const string LogEntryKind = "LogEntryKind"; 14 | internal const string TimeStamp = "TimeStamp"; 15 | 16 | internal const string ProtocolName = "ProtocolName"; 17 | internal const string ProtocolVersion = "ProtocolVersion"; 18 | 19 | internal const string ServerIPInfo = "ServerIPAddress"; 20 | internal const string ServerOSInfo = "ServerOS"; 21 | internal const string ServerOSVendor = "ServerOSVendor"; 22 | 23 | internal const string ClientName = "ClientName"; 24 | internal const string ClientOSInfo = "ClientOS"; 25 | 26 | internal const string TestCaseName = "TestCaseName"; 27 | internal const string TestName = "TestName"; 28 | internal const string TestResult = "TestResult"; 29 | internal const string TestStatus = "TestStatus"; 30 | 31 | internal const string ProtocolID = "ProtocolID"; 32 | internal const string ProtocolSection = "ProtocolSection"; 33 | 34 | internal const string PTFConfiguration = "PTFConfiguration"; 35 | 36 | internal const string TestsExecuted = "TestsExecuted"; 37 | 38 | private static Dictionary testStatusName; 39 | internal static Dictionary TestStatusName 40 | { 41 | get 42 | { 43 | if (testStatusName == null) 44 | { 45 | testStatusName = 46 | new Dictionary(); 47 | 48 | testStatusName.Add(PtfTestOutcome.Passed, "TestsPassed"); 49 | testStatusName.Add(PtfTestOutcome.Failed, "TestsFailed"); 50 | testStatusName.Add(PtfTestOutcome.Inconclusive, "TestsInconclusive"); 51 | testStatusName.Add(PtfTestOutcome.Error, "TestsError"); 52 | testStatusName.Add(PtfTestOutcome.Aborted, "TestsAborted"); 53 | testStatusName.Add(PtfTestOutcome.InProgress, "TestsInProgress"); 54 | testStatusName.Add(PtfTestOutcome.Timeout, "TestsTimeout"); 55 | testStatusName.Add(PtfTestOutcome.Unknown, "TestsUnknown"); 56 | } 57 | 58 | return testStatusName; 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Logging/LogProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using Microsoft.Protocols.TestTools; 8 | 9 | namespace Microsoft.Protocols.TestTools.Logging 10 | { 11 | /// 12 | /// Only for internal use. An abstract base class provides a specified group of log information. 13 | /// 14 | internal abstract class LogProvider 15 | { 16 | internal Dictionary info = new Dictionary(); 17 | 18 | /// 19 | /// Gets the log information. 20 | /// 21 | public virtual Dictionary Information 22 | { 23 | get { return info; } 24 | } 25 | 26 | /// 27 | /// Gets whether the information can be overridden. The default value is true. 28 | /// 29 | public virtual bool AllowOverride 30 | { 31 | get { return true; } 32 | } 33 | 34 | /// 35 | /// Initializes the LogProvider instances. 36 | /// 37 | /// The test site which this LogProvider is hosted in. 38 | public virtual void Initialize(ITestSite testSite) 39 | { 40 | } 41 | 42 | /// 43 | /// Prepares the log information according to the log entry information. This method will be called 44 | /// before the log entry is added to all sinks. 45 | /// 46 | /// Log information kind. 47 | /// Log information string. 48 | /// The timestamp when the log information is created. 49 | /// The current test runtime properties. 50 | public virtual void PrepareLogInformation( 51 | LogEntryKind kind, 52 | string message, 53 | DateTime timeStamp, 54 | Dictionary testProperties) 55 | { 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Logging/LoggingHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using System.Collections.Specialized; 8 | using System.ComponentModel; 9 | 10 | namespace Microsoft.Protocols.TestTools.Logging 11 | { 12 | /// 13 | /// This class contains supporting functions for logging. 14 | /// 15 | public sealed class LoggingHelper 16 | { 17 | private const string timeStampFormat = "{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}.{6:D3}"; 18 | 19 | /// 20 | /// Disabled default constructor. Only static methods are intent in this class. 21 | /// 22 | private LoggingHelper() 23 | { 24 | } 25 | 26 | /// 27 | /// Retrieve a specified string from the resource. 28 | /// 29 | /// Name of the string. 30 | /// An object array containing zero or more objects to format. 31 | /// The corresponding string in the resource. 32 | public static string GetString(string name, params object[] parameters) 33 | { 34 | //string str = Messages.ResourceManager.GetString(name); 35 | System.Reflection.FieldInfo field = typeof(Messages).GetField(name); 36 | string str = (string)field.GetValue(null); 37 | return String.Format(str, parameters); 38 | } 39 | 40 | /// 41 | /// Map a PtfTestOutcome value to its corresponding LogEntryKind value. 42 | /// 43 | /// Unit test outcome 44 | /// The log entry kind 45 | public static LogEntryKind PtfTestOutcomeToLogEntryKind(PtfTestOutcome unitTestOutcome) 46 | { 47 | LogEntryKind logEntryKind = LogEntryKind.TestUnknown; 48 | 49 | switch(unitTestOutcome) 50 | { 51 | case PtfTestOutcome.Failed: 52 | logEntryKind = LogEntryKind.TestFailed; 53 | break; 54 | case PtfTestOutcome.Inconclusive: 55 | logEntryKind = LogEntryKind.TestInconclusive; 56 | break; 57 | case PtfTestOutcome.Passed: 58 | logEntryKind = LogEntryKind.TestPassed; 59 | break; 60 | case PtfTestOutcome.InProgress: 61 | logEntryKind = LogEntryKind.TestInProgress; 62 | break; 63 | case PtfTestOutcome.Error: 64 | logEntryKind = LogEntryKind.TestError; 65 | break; 66 | case PtfTestOutcome.Timeout: 67 | logEntryKind = LogEntryKind.TestTimeout; 68 | break; 69 | case PtfTestOutcome.Aborted: 70 | logEntryKind = LogEntryKind.TestAborted; 71 | break; 72 | default: 73 | logEntryKind = LogEntryKind.TestUnknown; 74 | break; 75 | } 76 | 77 | return logEntryKind; 78 | } 79 | 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Logging/Messages.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Protocols.TestTools.Logging 5 | { 6 | /// 7 | /// A static class which contains the XML node names in the PTF configuration files. 8 | /// 9 | public static class Messages 10 | { 11 | // TODO: it seems dotnet core does not support l10n right now 12 | 13 | /// 14 | /// Looks up a localized string similar to Expected: <{0}>, Actual: <{1}>. {2}. 15 | /// 16 | public const string AreEqualFailMsg = "Expected: <{0}>, Actual: <{1}>. {2}"; 17 | 18 | /// 19 | /// Looks up a localized string similar to Expected: <{0}>, Actual: <{1}>. {2}. 20 | /// 21 | public const string AreNotEqualFailMsg = "Expected: <{0}>, Actual: <{1}>. {2}"; 22 | 23 | /// 24 | /// Looks up a localized string similar to {0}.{1} failed. {2}. 25 | /// 26 | public const string CheckFailed = "{0}.{1} failed. {2}"; 27 | 28 | /// 29 | /// Looks up a localized string similar to {0}.{1} failed on requirement {2}. {3}. 30 | /// 31 | public const string CheckFailedOnReqId = "{0}.{1} failed on requirement {2}. {3}"; 32 | 33 | /// 34 | /// Looks up a localized string similar to {0}.{1} is inconclusive. {2}. 35 | /// 36 | public const string CheckInconclusive = "{0}.{1} is inconclusive. {2}"; 37 | 38 | /// 39 | /// Looks up a localized string similar to {0}.{1} succeeded. {2}. 40 | /// 41 | public const string CheckSucceeded = "{0}.{1} succeeded. {2}"; 42 | 43 | /// 44 | /// Looks up a localized string similar to The kind of message log entry must match.. 45 | /// 46 | public const string EntryKindMissMatch = "The kind of message log entry must match."; 47 | 48 | /// 49 | /// Looks up a localized string similar to entryType does not implement the ILogEntry interface. 50 | /// 51 | public const string EntryTypeLogFilterArguementMessage = "entryType does not implement the ILogEntry interface"; 52 | 53 | /// 54 | /// Looks up a localized string similar to Expected Type: <{0}>, Actual Type: <{1}>. {2}. 55 | /// 56 | public const string IsInstanceOfFailMsg = "Expected Type: <{0}>, Actual Type: <{1}>. {2}"; 57 | 58 | /// 59 | /// Looks up a localized string similar to Wrong Type: <{0}>, Actual Type: <{1}>. {2}. 60 | /// 61 | public const string IsNotInstanceOfFailMsg = "Wrong Type: <{0}>, Actual Type: <{1}>. {2}"; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Logging/Sinks/PipeSink.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.IO; 9 | using System.IO.Pipes; 10 | 11 | namespace Microsoft.Protocols.TestTools.Logging 12 | { 13 | internal class PipeSink : LogSink 14 | { 15 | private const string PipeName = "PTFToolPipe"; 16 | 17 | private NamedPipeClientStream client; 18 | 19 | private StreamWriter sw; 20 | 21 | private const string timeStampFormat = "{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}.{6:D3}"; //e.g. 2007-05-16 16:50:23.412 22 | 23 | public PipeSink(string name) 24 | : base(name) 25 | { 26 | client = new NamedPipeClientStream(PipeName); 27 | try 28 | { 29 | client.Connect(1000); 30 | sw = new StreamWriter(client); 31 | } 32 | catch { sw = null; } 33 | } 34 | 35 | public PipeSink(string name, string identity) 36 | : base(name) 37 | { 38 | client = new NamedPipeClientStream(string.IsNullOrEmpty(identity) ? PipeName : identity); 39 | try 40 | { 41 | client.Connect(1000); 42 | sw = new StreamWriter(client); 43 | } 44 | catch { sw = null; } 45 | } 46 | 47 | protected override void OnWriteEntry(Dictionary information) 48 | { 49 | WriteAny( 50 | (LogEntryKind)information[LogInformationName.LogEntryKind], 51 | (string)information[LogInformationName.Message], 52 | (DateTime)information[LogInformationName.TimeStamp]); 53 | } 54 | 55 | protected override void OnWriteBeginGroup(Dictionary information) 56 | { 57 | WriteAny( 58 | (LogEntryKind)information[LogInformationName.LogEntryKind], 59 | (string)information[LogInformationName.Message], 60 | (DateTime)information[LogInformationName.TimeStamp]); 61 | base.OnWriteBeginGroup(information); 62 | } 63 | 64 | protected override void OnWriteEndGroup(Dictionary information) 65 | { 66 | base.OnWriteEndGroup(information); 67 | WriteAny( 68 | (LogEntryKind)information[LogInformationName.LogEntryKind], 69 | (string)information[LogInformationName.Message], 70 | (DateTime)information[LogInformationName.TimeStamp]); 71 | } 72 | 73 | protected override void Dispose(bool disposing) 74 | { 75 | base.Dispose(disposing); 76 | if (sw != null) 77 | { 78 | sw.Close(); 79 | sw = null; 80 | } 81 | client.Close(); 82 | } 83 | 84 | private void WriteAny(LogEntryKind kind, string message, DateTime timeStamp) 85 | { 86 | if (sw == null) return; 87 | if (!String.IsNullOrEmpty(message)) 88 | { 89 | try 90 | { 91 | sw.Write( 92 | timeStampFormat, // format sting 93 | timeStamp.Year, // paramters 94 | timeStamp.Month, 95 | timeStamp.Day, 96 | timeStamp.Hour, 97 | timeStamp.Minute, 98 | timeStamp.Second, 99 | timeStamp.Millisecond); 100 | sw.Write(String.Format(" [{0}] {1}\n", kind.ToString(), message)); 101 | } 102 | catch { sw = null; } 103 | } 104 | } 105 | 106 | public override void Flush() 107 | { 108 | if (sw == null) return; 109 | sw.Flush(); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/TestFramework/Core/RequirementId.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using System.Xml; 8 | 9 | namespace Microsoft.Protocols.TestTools 10 | { 11 | /// 12 | /// A class which creates the unified message for captured requirements. 13 | /// This class can be used from modeling code as well as from test suite code. 14 | /// 15 | public static class RequirementId 16 | { 17 | private static Dictionary dict = new Dictionary(); 18 | 19 | /// 20 | /// Makes a requirement entry, inserts into the requirement table if necessary, 21 | /// and returns the requirement ID. 22 | /// 23 | /// 24 | /// The decription of requirement string must be unique. If more than descriptions are specified for 25 | /// a requirement, an InvalidOperationException will be raised. 26 | /// 27 | /// The requirement specification document short name. 28 | /// The requirement number. 29 | /// The requirement description string. 30 | /// The requirement id. Format <docShortName>_R<number>. 31 | public static string Make(string docShortName, int number, string description) 32 | { 33 | if (String.IsNullOrEmpty(description) || 34 | String.IsNullOrEmpty(description.Trim())) 35 | { 36 | throw new ArgumentException("description can't be null or empty", "description"); 37 | } 38 | string reqId = MakeId(docShortName, number); 39 | 40 | if (!dict.ContainsKey(reqId)) 41 | { 42 | dict.Add(reqId, description); 43 | } 44 | else 45 | { 46 | if (dict[reqId] != description) 47 | throw new InvalidOperationException( 48 | String.Format( 49 | "Trying to override existed description with different new one.\r\nexisted description:{0}\r\nnew description:{1}", 50 | dict[reqId], 51 | description) 52 | ); 53 | } 54 | 55 | return reqId; 56 | } 57 | 58 | /// 59 | /// Empties the requirement table. 60 | /// 61 | public static void ClearRequirementTable() 62 | { 63 | dict.Clear(); 64 | } 65 | 66 | private static string MakeId(string docShortName, int number) 67 | { 68 | if (String.IsNullOrEmpty(docShortName) || 69 | String.IsNullOrEmpty(docShortName.Trim())) 70 | { 71 | throw new ArgumentException("docShortName can't be null or empty", "docShortName"); 72 | } 73 | if (number < 0) 74 | { 75 | throw new ArgumentException("number should be non-negative.", "number"); 76 | } 77 | string reqId = docShortName + "_R" + number; 78 | return reqId; 79 | } 80 | 81 | /// 82 | /// Gets the corresponding description by docShortName and number. 83 | /// 84 | /// Document short name, eg. MS-KILE 85 | /// Number in doc, eg. 24 86 | /// The description string, null if not found. 87 | internal static string GetDescription(string docShortName, int number) 88 | { 89 | return GetDescription(MakeId(docShortName, number)); 90 | } 91 | 92 | /// 93 | /// Gets the corresponding description by Requirement Id. 94 | /// 95 | /// Requirement id, eg. MS-KILE_24 96 | /// The description string, null if not found. 97 | internal static string GetDescription(string reqId) 98 | { 99 | if (String.IsNullOrEmpty(reqId)) 100 | { 101 | throw new ArgumentException("reqId can't be null or empty", "reqId"); 102 | } 103 | string description; 104 | if (dict.TryGetValue(reqId, out description)) 105 | { 106 | return description; 107 | } 108 | else 109 | { 110 | return null; 111 | } 112 | } 113 | 114 | internal static bool IsEmpty() 115 | { 116 | return (dict.Count == 0); 117 | } 118 | 119 | internal static IEnumerable> Entries 120 | { 121 | get 122 | { 123 | foreach (KeyValuePair kvp in dict) 124 | { 125 | yield return kvp; 126 | } 127 | } 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/TestFramework/Core/TestSiteProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using System.Diagnostics; 8 | using System.IO; 9 | using System.ComponentModel; 10 | 11 | namespace Microsoft.Protocols.TestTools 12 | { 13 | /// 14 | /// FOR INTERNAL USE ONLY. 15 | /// A static class which manages the test site used throughout a series of test suite executions. 16 | /// 17 | internal static class TestSiteProvider 18 | { 19 | static Dictionary testSites; 20 | static object asyncCleanupLock = new object(); 21 | 22 | /// 23 | /// Initializes the current test site, based on test test context and test suite name. 24 | /// If a current test site exists which does have same test suite name, 25 | /// it will be reused, otherwise a new one will be created, otherwise the current one 26 | /// will be reused. 27 | /// 28 | /// Configuration data from ptfconfig 29 | /// 30 | /// 31 | /// Test assembly name 32 | public static void Initialize( 33 | IConfigurationData config, IProtocolTestContext context, string testSuiteName, string testAssemblyName) 34 | { 35 | if (context == null) 36 | { 37 | throw new ArgumentNullException("context", "Test context cannot be null."); 38 | } 39 | 40 | Initialize(config, context.TestAssemblyDir, context.PtfconfigDir, testSuiteName, testAssemblyName); 41 | } 42 | 43 | /// 44 | /// Initializes the current test site, using the given config search path and test suite name. 45 | /// If a current test site exists which does have same test suite name, 46 | /// it will be reused, otherwise a new one will be created, otherwise the current one 47 | /// will be reused. 48 | /// 49 | /// Configuration data from ptfconfig 50 | /// 51 | /// 52 | /// 53 | /// Test assembly name 54 | public static void Initialize( 55 | IConfigurationData config, string testAssemblyPath, string ptfconfigPath, string testSuiteName, string testAssemblyName) 56 | { 57 | if (string.IsNullOrEmpty(testAssemblyPath)) 58 | { 59 | throw new ArgumentException("testAssemblyPath cannot be null or empty.", "testAssemblyPath"); 60 | } 61 | 62 | if (string.IsNullOrEmpty(ptfconfigPath)) 63 | { 64 | throw new ArgumentException("ptfconfigPath cannot be null or empty.", "ptfconfigPath"); 65 | } 66 | 67 | 68 | InitializeTestSite(config, testAssemblyPath, ptfconfigPath, testSuiteName, PtfTestOutcome.Unknown, testAssemblyName); 69 | } 70 | 71 | private static void InitializeTestSite( 72 | IConfigurationData config, 73 | string testAssemblyPath, 74 | string ptfconfigPath, 75 | string testSuiteName, 76 | PtfTestOutcome currentTestOutCome, 77 | string testAssemblyName) 78 | { 79 | if (null == config) 80 | { 81 | throw new ArgumentException("config cannot be null."); 82 | } 83 | 84 | if (testSites == null) 85 | { 86 | testSites = new Dictionary(); 87 | } 88 | 89 | if (!testSites.ContainsKey(testSuiteName)) 90 | { 91 | DefaultTestSite testSite = new DefaultTestSite(config, testAssemblyPath, ptfconfigPath, testSuiteName, testAssemblyName); 92 | 93 | testSites.Add(testSuiteName, testSite); 94 | } 95 | else 96 | { 97 | testSites[testSuiteName].DisposeAdapters(); 98 | } 99 | 100 | testSites[testSuiteName].TestProperties[TestPropertyNames.CurrentTestCaseName] = null; 101 | testSites[testSuiteName].TestProperties[TestPropertyNames.CurrentTestOutcome] = currentTestOutCome; 102 | } 103 | 104 | public static ITestSite GetTestSite(string testSuiteName) 105 | 106 | { 107 | if (testSites == null || (!testSites.ContainsKey(testSuiteName))) 108 | { 109 | return null; 110 | } 111 | return testSites[testSuiteName]; 112 | } 113 | 114 | public static IProtocolTestNotify GetProtocolTestNotify(string testSuiteName) 115 | 116 | { 117 | if (testSites == null || (!testSites.ContainsKey(testSuiteName))) 118 | { 119 | return null; 120 | } 121 | return testSites[testSuiteName]; 122 | } 123 | 124 | /// 125 | /// Cleans up the current test site. This method closes the log and disposes the test site. 126 | /// 127 | public static void Cleanup() 128 | { 129 | lock (asyncCleanupLock) 130 | { 131 | if (testSites != null) 132 | { 133 | foreach (KeyValuePair kvp in testSites) 134 | { 135 | if (kvp.Value != null) 136 | { 137 | kvp.Value.Dispose(); 138 | } 139 | } 140 | testSites.Clear(); 141 | } 142 | } 143 | } 144 | 145 | public static void DisposeTestSite(string testSuiteName) 146 | { 147 | lock (asyncCleanupLock) 148 | { 149 | if (testSites != null && testSites.ContainsKey(testSuiteName)) 150 | { 151 | testSites[testSuiteName].Dispose(); 152 | testSites.Remove(testSuiteName); 153 | } 154 | } 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/TestFramework/Core/Variable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Microsoft.Protocols.TestTools.Messages.Runtime; 5 | using System; 6 | 7 | namespace Microsoft.Protocols.TestTools 8 | { 9 | /// 10 | /// Type representing a transacted variable. 11 | /// 12 | /// 13 | public interface IVariable 14 | { 15 | /// 16 | /// Determines whether the variable is bound. 17 | /// 18 | bool IsBound { get; } 19 | 20 | /// 21 | /// Resets the variable to unbound state, so that it 22 | /// can be bound to new value later. 23 | /// 24 | void Unbind(); 25 | 26 | /// 27 | /// Gets or sets a value. If the variable is bound, setting 28 | /// will result in an equality check on its current value 29 | /// with the given value. If the variable is unbound, getting 30 | /// will result in generation of a default value. 31 | /// 32 | T Value { get; set; } 33 | } 34 | 35 | abstract class VariableBase 36 | { 37 | internal abstract void InternalUnbind(); 38 | internal abstract string Name { get; } 39 | internal abstract object ObjectValue { get; } 40 | } 41 | 42 | class Variable : VariableBase, IVariable 43 | { 44 | string name; 45 | T value; 46 | bool isBound; 47 | IProtocolTestsManager manager; 48 | 49 | internal Variable(string name, IProtocolTestsManager manager) 50 | { 51 | this.name = name; 52 | this.manager = manager; 53 | } 54 | 55 | public void Unbind() 56 | { 57 | InternalUnbind(); 58 | } 59 | 60 | internal override void InternalUnbind() 61 | { 62 | isBound = false; 63 | value = default(T); 64 | } 65 | 66 | internal override string Name 67 | { 68 | get { return name; } 69 | } 70 | 71 | internal override object ObjectValue 72 | { 73 | get { return value; } 74 | } 75 | 76 | #region IVariable 77 | 78 | /// 79 | /// Determines whether the variable is bound. 80 | /// 81 | public bool IsBound 82 | { 83 | get { return isBound; } 84 | } 85 | 86 | 87 | /// 88 | /// Gets or sets a value. If the variable is bound, setting 89 | /// will result in an equality check on its current value 90 | /// with the given value. If the variable is unbound, getting 91 | /// will result in generation of a default value. 92 | /// 93 | public T Value 94 | { 95 | get 96 | { 97 | if (!isBound) 98 | { 99 | throw new UnboundVariableException("Variable's value cannot be read before it is bound"); 100 | } 101 | return value; 102 | } 103 | set 104 | { 105 | if (!isBound) 106 | { 107 | this.value = value; 108 | isBound = true; 109 | } 110 | else 111 | { 112 | manager.Assert(Object.Equals(this.value, value), 113 | String.Format( 114 | "bound variable '{0}' can only be assigned to equal value (bound value: '{1}', new value: '{2}')", 115 | this.name, this.value, value)); 116 | } 117 | } 118 | } 119 | 120 | #endregion 121 | } 122 | 123 | /// 124 | /// TransactionEventKind 125 | /// 126 | public enum TransactionEventKind 127 | { 128 | /// 129 | /// Assert 130 | /// 131 | Assert, 132 | /// 133 | /// Assume 134 | /// 135 | Assume, 136 | /// 137 | /// Checkpoint 138 | /// 139 | Checkpoint, 140 | /// 141 | /// Comment 142 | /// 143 | Comment, 144 | /// 145 | /// VariableBound 146 | /// 147 | VariableBound 148 | } 149 | 150 | /// 151 | /// TransactionEvent 152 | /// 153 | public struct TransactionEvent 154 | { 155 | internal TransactionEventKind Kind; 156 | internal bool condition; 157 | internal string description; 158 | internal VariableBase variable; 159 | 160 | internal TransactionEvent(TransactionEventKind kind, bool condition, string description, VariableBase variable) 161 | { 162 | this.Kind = kind; 163 | this.condition = condition; 164 | this.description = description; 165 | this.variable = variable; 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/TestFramework/Messages/AvailableReturn.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Reflection; 6 | using System.Text; 7 | 8 | namespace Microsoft.Protocols.TestTools.Messages.Runtime 9 | { 10 | /// 11 | /// A type to describe an available return. 12 | /// 13 | public class AvailableReturn 14 | { 15 | /// 16 | /// The method identifier by 17 | /// its reflection representation, 18 | /// 19 | public MethodBase Method 20 | { 21 | get; 22 | private set; 23 | } 24 | 25 | /// 26 | /// The parameters passed to the return. 27 | /// 28 | public object[] Parameters 29 | { 30 | get; 31 | private set; 32 | } 33 | 34 | /// 35 | /// construct 36 | /// 37 | /// 38 | /// 39 | public AvailableReturn(MethodBase methodInfo, object[] parameters) 40 | { 41 | this.Method = methodInfo; 42 | this.Parameters = parameters; 43 | } 44 | 45 | /// 46 | /// Delivers readable representation. 47 | /// 48 | /// 49 | public override string ToString() 50 | { 51 | StringBuilder result = new StringBuilder(); 52 | result.Append("return "); 53 | result.Append(Method.Name); 54 | result.Append("("); 55 | bool first = true; 56 | Type returnType; 57 | if (Method is MethodInfo) 58 | returnType = ((MethodInfo)Method).ReturnType; 59 | else 60 | returnType = null; 61 | bool hasReturn = returnType != null && returnType != typeof(void); 62 | int i = hasReturn ? 1 : 0; 63 | foreach (ParameterInfo pinfo in Method.GetParameters()) 64 | { 65 | if (pinfo.ParameterType.IsByRef) 66 | { 67 | if (first) 68 | first = false; 69 | else 70 | result.Append(","); 71 | if ((pinfo.Attributes & ParameterAttributes.Out) != ParameterAttributes.None) 72 | result.Append("out "); 73 | else 74 | result.Append("ref "); 75 | result.Append(Parameters[i++]); 76 | } 77 | } 78 | result.Append(")"); 79 | if (hasReturn) 80 | { 81 | result.Append("/"); 82 | result.Append(MessageRuntimeHelper.Describe(Parameters[0])); 83 | } 84 | return result.ToString(); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/TestFramework/Messages/Exceptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Protocols.TestTools.Messages.Runtime 7 | { 8 | /// 9 | /// An exception which is thrown when variable is read before it is bound. 10 | /// 11 | [Serializable] 12 | public class UnboundVariableException : Exception 13 | { 14 | /// 15 | /// Constructs the UnboundVariableException. 16 | /// 17 | public UnboundVariableException() 18 | : base() 19 | { } 20 | 21 | /// 22 | /// Constructs the UnboundVariableException. 23 | /// 24 | /// error message 25 | public UnboundVariableException(string message) 26 | : base(message) 27 | { 28 | } 29 | 30 | /// 31 | /// Constructs the UnboundVariableException. 32 | /// 33 | /// 34 | /// The inner exception. 35 | public UnboundVariableException(string message, Exception innerException) 36 | : base(message, innerException) 37 | { 38 | } 39 | } 40 | 41 | /// 42 | /// An exception which is thrown when assertion failure is hit. 43 | /// 44 | [Serializable] 45 | public class TestFailureException : Exception 46 | { 47 | /// 48 | /// Constructs the TestFailureException. 49 | /// 50 | public TestFailureException() 51 | : base() 52 | { } 53 | 54 | /// 55 | /// Constructs the TestFailureException. 56 | /// 57 | /// error message 58 | public TestFailureException(string message) 59 | : base(message) 60 | { 61 | } 62 | 63 | /// 64 | /// Constructs the TestFailureException. 65 | /// 66 | /// 67 | /// The inner exception. 68 | public TestFailureException(string message, Exception innerException) 69 | : base(message, innerException) 70 | { 71 | } 72 | } 73 | 74 | /// 75 | /// Class representing the exceptional case of a failed transaction. 76 | /// 77 | [Serializable] 78 | public class TransactionFailedException : Exception 79 | { 80 | /// 81 | /// Constructs transaction failed exception 82 | /// 83 | public TransactionFailedException() 84 | : base() 85 | { 86 | } 87 | 88 | /// 89 | /// Constructs transaction failed exception 90 | /// 91 | /// The message text. 92 | public TransactionFailedException(string message) 93 | : base(message) 94 | { 95 | } 96 | 97 | /// 98 | /// Constructs transaction failed exception 99 | /// 100 | /// The message text. 101 | /// The inner exception. 102 | public TransactionFailedException(string message, Exception innerException) 103 | : base(message, innerException) 104 | { 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/TestFramework/Messages/ExpectedEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Reflection; 6 | using System.Text; 7 | 8 | namespace Microsoft.Protocols.TestTools.Messages.Runtime 9 | { 10 | /// 11 | /// A type to describe an expected event. 12 | /// 13 | public struct ExpectedEvent 14 | { 15 | /// 16 | /// The event waited for, identified by its 17 | /// reflection representation. 18 | /// 19 | public EventInfo Event 20 | { 21 | get; 22 | private set; 23 | } 24 | 25 | /// 26 | /// The target of the event (the instance object where the event 27 | /// belongs too), or null, if it is a static or an adapter event. 28 | /// 29 | public object Target 30 | { 31 | get; 32 | private set; 33 | } 34 | 35 | /// 36 | /// The checker to be called when the event 37 | /// arrives. 38 | /// 39 | public Delegate Checker 40 | { 41 | get; 42 | private set; 43 | } 44 | 45 | /// 46 | /// Constructs an expected event. 47 | /// 48 | /// The reflection information of the event. 49 | /// The target object. Must be null for static events and for adapter events. 50 | /// 51 | /// The checker. Must match the type of the event. A compatible type is a delegate type 52 | /// either taking an array of objects as arguments, exactly the arguments of the event, or 53 | /// exactly the arguments of the event preceded by an instance of the event target. 54 | /// 55 | /// 56 | public ExpectedEvent(EventInfo eventInfo, object target, Delegate checker) : this() 57 | { 58 | this.Event = eventInfo; 59 | this.Target = target; 60 | this.Checker = checker; 61 | } 62 | 63 | /// 64 | /// Delivers readable representation. 65 | /// 66 | /// 67 | public override string ToString() 68 | { 69 | StringBuilder result = new StringBuilder(); 70 | if (Target != null) 71 | { 72 | result.Append(MessageRuntimeHelper.Describe(Target)); 73 | result.Append("."); 74 | } 75 | result.Append("event "); 76 | result.Append(Event.Name); 77 | result.Append("(...)"); 78 | return result.ToString(); 79 | } 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/TestFramework/Messages/ExpectedPreConstraint.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Protocols.TestTools.Messages.Runtime 7 | { 8 | /// 9 | /// A type to describe an expected pre constraint 10 | /// 11 | public struct ExpectedPreConstraint 12 | { 13 | /// 14 | /// The checker to be called when test manager intend to check preconstraint attached to transition. 15 | /// 16 | /// 17 | /// The checker has no parameter or return value. 18 | /// 19 | public Delegate Checker 20 | { 21 | get; 22 | private set; 23 | } 24 | 25 | /// 26 | /// The constructor. 27 | /// 28 | /// 29 | public ExpectedPreConstraint(Delegate checker) : this() 30 | { 31 | this.Checker = checker; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/TestFramework/Messages/ExpectedReturn.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Reflection; 6 | using System.Text; 7 | 8 | namespace Microsoft.Protocols.TestTools.Messages.Runtime 9 | { 10 | /// 11 | /// A type to describe an expected method return. 12 | /// 13 | public struct ExpectedReturn 14 | { 15 | /// 16 | /// The method for which a return is expected, 17 | /// identified by its reflection representation 18 | /// 19 | public MethodBase Method 20 | { 21 | get; 22 | private set; 23 | } 24 | 25 | /// 26 | /// The target of the method (the instance object where the method 27 | /// belongs too), or null, if it is a static or an adapter method. 28 | /// 29 | public object Target 30 | { 31 | get; 32 | private set; 33 | } 34 | 35 | /// 36 | /// The checker to be called when the method return 37 | /// arrives. 38 | /// 39 | public Delegate Checker 40 | { 41 | get; 42 | private set; 43 | } 44 | 45 | /// 46 | /// Constructs an expected method return. 47 | /// 48 | /// The reflection information of the method. 49 | /// The target object. Must be null for static methods and for adapter methods. 50 | /// 51 | /// The checker. Must match the type of the method. A compatible type is a delegate type 52 | /// either taking an array of objects as arguments, exactly the arguments of the method outputs, or 53 | /// exactly the arguments of the method outputs preceded by an instance of the method target. 54 | /// 55 | /// 56 | public ExpectedReturn(MethodBase methodInfo, object target, Delegate checker) : this() 57 | { 58 | this.Method = methodInfo; 59 | this.Target = target; 60 | this.Checker = checker; 61 | } 62 | 63 | /// 64 | /// Delivers readable representation. 65 | /// 66 | /// 67 | public override string ToString() 68 | { 69 | StringBuilder result = new StringBuilder(); 70 | if (Target != null) 71 | { 72 | result.Append(MessageRuntimeHelper.Describe(Target)); 73 | result.Append("."); 74 | } 75 | result.Append("event "); 76 | result.Append(Method.Name); 77 | result.Append("(...)"); 78 | return result.ToString(); 79 | } 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/TestFramework/Messages/MessageRuntimeHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.IO; 6 | using System.Text; 7 | using System.Collections.Generic; 8 | using System.Reflection; 9 | using Microsoft.Win32; 10 | 11 | namespace Microsoft.Protocols.TestTools.Messages 12 | { 13 | /// 14 | /// Provides a series of helper methods in message runtime module 15 | /// 16 | public static class MessageRuntimeHelper 17 | { 18 | /// 19 | /// Describes a (possibly symbolic) value. 20 | /// 21 | /// type 22 | /// (possibly symbolic) value 23 | /// description 24 | public static string Describe(T value) 25 | { 26 | if (value == null) 27 | return "null"; 28 | Type type = value.GetType(); 29 | if (IsStruct(type)) 30 | { 31 | 32 | MethodInfo methodInfo = type.GetMethod("ToString", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); 33 | if (methodInfo == null) 34 | { 35 | FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 36 | bool first = true; 37 | StringBuilder sb = new StringBuilder(); 38 | sb.AppendFormat("{0}(", type.Name); 39 | foreach (FieldInfo field in fields) 40 | { 41 | if (!first) 42 | sb.Append(","); 43 | else 44 | first = false; 45 | sb.AppendFormat("{0}=", field.Name); 46 | object fieldValue = field.GetValue((object)value); 47 | sb.AppendFormat("{0}", Describe(fieldValue)); 48 | } 49 | sb.Append(")"); 50 | return sb.ToString(); 51 | } 52 | else 53 | { 54 | object result = methodInfo.Invoke((object)value, null); 55 | return result as string; 56 | } 57 | } 58 | 59 | return value.ToString(); 60 | } 61 | 62 | 63 | #region helper methods 64 | /// 65 | /// Check if the given type is a Struct 66 | /// 67 | /// type to check 68 | /// True if the type is a struct; False if not. 69 | private static bool IsStruct(Type type) 70 | { 71 | if (type.IsValueType && !type.IsPrimitive && !type.IsEnum) 72 | { 73 | return true; 74 | } 75 | else 76 | { 77 | return false; 78 | } 79 | } 80 | 81 | #endregion helper methods 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/TestFramework/Messages/ObservationQueue.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | using System.Threading; 9 | 10 | namespace Microsoft.Protocols.TestTools.Messages 11 | { 12 | /// 13 | /// Implements a simple thread-safe queue used for observing events and returns. 14 | /// 15 | /// 16 | public class ObservationQueue 17 | { 18 | object queueLock = new object(); 19 | object queueFullLock = new object(); 20 | Queue queue = new Queue(); 21 | int maxQueueSize; 22 | 23 | /// 24 | /// Constructs a queue with the given maximal size. 25 | /// 26 | /// 27 | public ObservationQueue(int maxSize) 28 | { 29 | this.maxQueueSize = maxSize; 30 | } 31 | 32 | /// 33 | /// Adds an item to the queue. Will block if queue 34 | /// is currently full. 35 | /// 36 | /// 37 | public void Add(T item) 38 | { 39 | lock (queueLock) 40 | { 41 | queue.Enqueue(item); 42 | Monitor.Pulse(queueLock); 43 | } 44 | } 45 | 46 | /// 47 | /// Tries to get an item from the queue. 48 | /// 49 | /// 50 | /// 51 | /// 52 | /// 53 | public bool TryGet(TimeSpan timeOut, bool consume, out T item) 54 | { 55 | lock (queueLock) 56 | { 57 | if (queue.Count == 0) 58 | { 59 | Monitor.Wait(queueLock, timeOut); 60 | if (queue.Count == 0) 61 | { 62 | item = default(T); 63 | return false; 64 | } 65 | } 66 | if (consume) 67 | { 68 | item = queue.Dequeue(); 69 | } 70 | else 71 | item = queue.Peek(); 72 | } 73 | if (consume) 74 | lock (queueFullLock) 75 | Monitor.PulseAll(queueFullLock); 76 | return true; 77 | } 78 | 79 | /// 80 | /// Returns a copy of the queue content as a list. 81 | /// 82 | /// 83 | public IList GetEnumerator() 84 | { 85 | lock (queueLock) 86 | return new List(queue); 87 | } 88 | 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/TestFramework/Resources/Microsoft.Protocols.TestTools.AdapterConsole.runtimeconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeOptions": { 3 | "tfm": "net6.0", 4 | "framework": { 5 | "name": "Microsoft.NETCore.App", 6 | "version": "6.0.0" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /src/TestFramework/Resources/Schema/TestLog.xsd: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/TestFramework/Resources/packageIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ProtocolTestFramework/31124e75aae9d31fec9d19c10100ef9dd4a426d9/src/TestFramework/Resources/packageIcon.png -------------------------------------------------------------------------------- /src/TestFramework/Resources/site.ptfconfig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/TestFramework/TestFramework.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0;net7.0;net8.0 5 | Microsoft.Protocols.TestTools 6 | Microsoft.Protocols.TestTools 7 | Microsoft.Protocols.TestTools 8 | Microsoft Protocol Test Framework 9 | true 10 | true 11 | false 12 | 13 | 14 | 15 | 16 | 17 | Never 18 | 19 | 20 | 21 | True 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | Always 36 | 37 | 38 | Always 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | PreserveNewest 69 | 70 | 71 | Always 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/TestFramework/TestFramework.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Microsoft.Protocols.TestTools 5 | 2.5.0 6 | Protocol Test Framework 7 | Microsoft 8 | Microsoft 9 | packageIcon.png 10 | false 11 | LICENSE.txt 12 | https://github.com/microsoft/ProtocolTestFramework 13 | The Protocol Test Framework (PTF) is designed to support Microsoft Protocol Test Suites for both Windows and Office Protocol Interoperability testing. 14 | © Microsoft Corporation. All rights reserved. 15 | TestFramework Testing ProtocolTest 16 | 17 | 1. The PTF now supports .NET 6, .NET 7 and .NET 8. 18 | 2. The dependent MSTest.TestFramework is upgraded to 3.2.2. 19 | 3. The dependent PowerShell Core SDK is upgraded to 7.4.1. 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/TestFramework/TestTools.cd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | DefaultTestSite.cs 12 | 13 | 14 | 15 | 16 | kI4AqEAgAmBBAJCCGTCQEBIpAcyABCACyDADCBBDIgg= 17 | DefaultTestSite.cs 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | AAQACAAgAkBAAICACSAQEAIJAQyAACAAQCADCBBDIgA= 35 | ITestSite.cs 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | AAIAAAAAAAAAgAAAEAEAAAAAAAAAAAAAAAAACAAAAAA= 51 | ILogger.cs 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | AAAABKAAAAQAgAgAAAQAAIhBAAAAAAAYgAAAEQEAAAA= 66 | IChecker.cs 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | AAAAAAAAAAAAhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 76 | IAdapter.cs 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | AIQAAAAAAABQAgAAAACIQAACBIAEAAAAAAAggAACAAA= 86 | IConfigurationData.cs 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /src/TestFramework/VSTS/Checking/CheckException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Microsoft.Protocols.TestTools.Checking 9 | { 10 | /// 11 | /// An exception which is thrown when a debugging check result is failed or inconclusive. 12 | /// 13 | [Serializable] 14 | public class TestDebugException : Exception 15 | { 16 | /// 17 | /// Constructs a new instance of TestDebugException. 18 | /// 19 | public TestDebugException() { } 20 | 21 | /// 22 | /// Initializes a new instance of TestDebugException with a specified error message. 23 | /// 24 | /// The error message that explains the reason for the exception. 25 | public TestDebugException(string message) : base(message) { } 26 | 27 | /// 28 | /// Initializes a new instance of TestDebugException with a specified error message and an inner exception. 29 | /// 30 | /// The error message that explains the reason for the exception. 31 | /// The exception that is the cause of the current exception. If the parameter is not a 32 | /// null reference, the current exception is raised in a catch block that handles 33 | /// the inner exception. 34 | public TestDebugException(string message, Exception inner) : base(message, inner) { } 35 | 36 | /// 37 | /// Initializes a new instance of the TestDebugException class with serialized data. 38 | /// 39 | /// The SerializationInfo that holds the serialized object data about the exception being thrown. 40 | /// The StreamingContext that contains contextual information about the source or destination. 41 | protected TestDebugException( 42 | System.Runtime.Serialization.SerializationInfo info, 43 | System.Runtime.Serialization.StreamingContext context) 44 | : base(info, context) { } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/TestFramework/VSTS/Checking/CheckerTypes.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using Microsoft.VisualStudio.TestTools.UnitTesting; 8 | 9 | namespace Microsoft.Protocols.TestTools.Checking 10 | { 11 | /// 12 | /// The default assertion checker which is compatible with VSTS. 13 | /// 14 | public class DefaultAssertChecker : DefaultChecker 15 | { 16 | /// 17 | /// Constructs a new instance of DefaultAssertChecker. 18 | /// 19 | /// The test site which the checker is hosted on. 20 | /// The configuration to checker. 21 | public DefaultAssertChecker(ITestSite testSite, ICheckerConfig checkerConfig) 22 | : base(testSite, "Assert", LogEntryKind.CheckFailed, LogEntryKind.CheckSucceeded, LogEntryKind.CheckInconclusive, checkerConfig) 23 | { 24 | } 25 | 26 | /// 27 | /// Creates a failure exception for . 28 | /// 29 | /// A message that describes the exception. 30 | /// 31 | /// An instance of AssertFailedException. 32 | /// 33 | protected override AssertFailedException CreateFailException(string message) 34 | { 35 | return new AssertFailedException(message); 36 | } 37 | 38 | /// 39 | /// Creates an inconclusive exception for . 40 | /// 41 | /// A message that describes the exception. 42 | /// 43 | /// An instance of AssertInconclusiveException. 44 | /// 45 | protected override AssertInconclusiveException CreateInconclusiveException(string message) 46 | { 47 | return new AssertInconclusiveException(message); 48 | } 49 | } 50 | 51 | /// 52 | /// The default assumption checker which is compatible with VSTS. 53 | /// 54 | public class DefaultAssumeChecker : DefaultChecker 55 | { 56 | /// 57 | /// Constructs a new instance of DefaultAssumeChecker. 58 | /// 59 | /// The test site which the checker is hosted on. 60 | /// The configuration to checker. 61 | public DefaultAssumeChecker(ITestSite testSite, ICheckerConfig checkerConfig) 62 | : base(testSite, "Assume", LogEntryKind.CheckFailed, LogEntryKind.CheckSucceeded, LogEntryKind.CheckInconclusive, checkerConfig) 63 | { 64 | } 65 | 66 | /// 67 | /// Creates a failure exception for . 68 | /// 69 | /// A message that describes the exception. 70 | /// 71 | /// An instance of AssertInconclusiveException. 72 | /// 73 | protected override AssertInconclusiveException CreateFailException(string message) 74 | { 75 | return new AssertInconclusiveException(message); 76 | } 77 | 78 | /// 79 | /// Creates an inconclusive exception for . 80 | /// 81 | /// A message that describes the exception. 82 | /// 83 | /// An instance of AssertInconclusiveException. 84 | /// 85 | protected override AssertInconclusiveException CreateInconclusiveException(string message) 86 | { 87 | return new AssertInconclusiveException(message); 88 | } 89 | } 90 | 91 | /// 92 | /// The default debug checker which is compatible with VSTS. 93 | /// 94 | public class DefaultDebugChecker : DefaultChecker 95 | { 96 | /// 97 | /// Constructs a new instance of DefaultDebugChecker. 98 | /// 99 | /// The test site which the checker is hosted on. 100 | /// The configuration to checker. 101 | public DefaultDebugChecker(ITestSite testSite, ICheckerConfig checkerConfig) 102 | : base(testSite, "Debug", LogEntryKind.Debug, LogEntryKind.Debug, LogEntryKind.Debug, checkerConfig) 103 | { 104 | } 105 | 106 | /// 107 | /// Creates a failure exception for . 108 | /// 109 | /// A message that describes the exception. 110 | /// 111 | /// An instance of . 112 | /// 113 | protected override TestDebugException CreateFailException(string message) 114 | { 115 | return new TestDebugException(message); 116 | } 117 | 118 | /// 119 | /// Creates an inconclusive exception for . 120 | /// 121 | /// A message that describes the exception. 122 | /// 123 | /// An instance of . 124 | /// 125 | protected override TestDebugException CreateInconclusiveException(string message) 126 | { 127 | return new TestDebugException(message); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/TestFramework/VSTS/VstsTestContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Reflection; 8 | using System.Text; 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | 11 | namespace Microsoft.Protocols.TestTools 12 | { 13 | class VstsTestContext:IProtocolTestContext 14 | { 15 | TestContext context; 16 | string testAssemblyDir; 17 | 18 | public VstsTestContext(TestContext context) 19 | { 20 | this.context = context; 21 | 22 | string assemblyPath = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath; 23 | this.testAssemblyDir = Path.GetDirectoryName(assemblyPath); 24 | } 25 | 26 | #region IProtocolTestContext Members 27 | 28 | public string TestAssemblyDir 29 | { 30 | get 31 | { 32 | return testAssemblyDir; 33 | } 34 | } 35 | 36 | public string PtfconfigDir 37 | { 38 | get 39 | { 40 | if (context.Properties.Contains("PtfconfigDirectory")) 41 | { 42 | return (string)context.Properties["PtfconfigDirectory"]; 43 | } 44 | else 45 | { 46 | return testAssemblyDir; 47 | } 48 | } 49 | } 50 | 51 | public PtfTestOutcome TestOutcome 52 | { 53 | get 54 | { 55 | if (context == null) 56 | { 57 | throw new InvalidOperationException( 58 | "The Protocol Test Context can't be null"); 59 | } 60 | 61 | return UnitTestOutcomeToPtfTestOutcome(context.CurrentTestOutcome); 62 | } 63 | } 64 | 65 | public string TestMethodName 66 | { 67 | get 68 | { 69 | if (context == null) 70 | { 71 | throw new InvalidOperationException( 72 | "The Protocol Test Context can't be null"); 73 | } 74 | 75 | return context.TestName; 76 | } 77 | } 78 | 79 | internal void Update(TestContext newContext) 80 | { 81 | if (this.context != newContext) 82 | { 83 | this.context = newContext; 84 | } 85 | } 86 | 87 | private static PtfTestOutcome UnitTestOutcomeToPtfTestOutcome(UnitTestOutcome uto) 88 | { 89 | PtfTestOutcome pto = PtfTestOutcome.Unknown; 90 | switch (uto) 91 | { 92 | case UnitTestOutcome.Failed: 93 | pto = PtfTestOutcome.Failed; 94 | break; 95 | case UnitTestOutcome.Inconclusive: 96 | pto = PtfTestOutcome.Inconclusive; 97 | break; 98 | case UnitTestOutcome.Passed: 99 | pto = PtfTestOutcome.Passed; 100 | break; 101 | case UnitTestOutcome.InProgress: 102 | pto = PtfTestOutcome.InProgress; 103 | break; 104 | case UnitTestOutcome.Error: 105 | pto = PtfTestOutcome.Error; 106 | break; 107 | case UnitTestOutcome.Timeout: 108 | pto = PtfTestOutcome.Timeout; 109 | break; 110 | case UnitTestOutcome.Aborted: 111 | pto = PtfTestOutcome.Aborted; 112 | break; 113 | default: 114 | pto = PtfTestOutcome.Unknown; 115 | break; 116 | } 117 | 118 | return pto; 119 | } 120 | 121 | #endregion 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/TestFramework/build/Microsoft.Protocols.TestTools.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreserveNewest 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/UnitTest/Base.ptfconfig: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/UnitTest/PowerShell/CalledByAnotherScript.ps1: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Copyright (c) Microsoft. All rights reserved. 3 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 4 | ############################################################################# 5 | 6 | Param( 7 | [string]$echo 8 | ) 9 | 10 | return $echo 11 | -------------------------------------------------------------------------------- /src/UnitTest/PowerShell/NestedCall.ps1: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Copyright (c) Microsoft. All rights reserved. 3 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 4 | ############################################################################# 5 | 6 | $result = ./CalledByAnotherScript -echo $str 7 | return $result 8 | -------------------------------------------------------------------------------- /src/UnitTest/PowerShell/ReturnBool.ps1: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Copyright (c) Microsoft. All rights reserved. 3 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 4 | ############################################################################# 5 | 6 | return $value 7 | -------------------------------------------------------------------------------- /src/UnitTest/PowerShell/ReturnInt.ps1: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Copyright (c) Microsoft. All rights reserved. 3 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 4 | ############################################################################# 5 | 6 | return $number 7 | -------------------------------------------------------------------------------- /src/UnitTest/PowerShell/ReturnString.ps1: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Copyright (c) Microsoft. All rights reserved. 3 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 4 | ############################################################################# 5 | 6 | return $str 7 | -------------------------------------------------------------------------------- /src/UnitTest/PowerShell/TestTimeout.ps1: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Copyright (c) Microsoft. All rights reserved. 3 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 4 | ############################################################################# 5 | Start-Sleep -s 61 6 | return $number 7 | -------------------------------------------------------------------------------- /src/UnitTest/PowerShell/ThrowException.ps1: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Copyright (c) Microsoft. All rights reserved. 3 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 4 | ############################################################################# 5 | 6 | # Throw an exception 7 | throw $exceptionMessage 8 | -------------------------------------------------------------------------------- /src/UnitTest/Shell/GetPtfProp.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft. All rights reserved. 2 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | echo $PTFProp_FeatureName -------------------------------------------------------------------------------- /src/UnitTest/Shell/ReturnBool.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft. All rights reserved. 2 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | result=$1 4 | echo $result 5 | -------------------------------------------------------------------------------- /src/UnitTest/Shell/ReturnInt.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft. All rights reserved. 2 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | num=$1 4 | echo $num 5 | -------------------------------------------------------------------------------- /src/UnitTest/Shell/ReturnString.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft. All rights reserved. 2 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | str=$1 4 | echo $str -------------------------------------------------------------------------------- /src/UnitTest/Shell/ThrowException.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft. All rights reserved. 2 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | exception=$1 4 | echo $exception >&2 5 | exit 1 6 | -------------------------------------------------------------------------------- /src/UnitTest/TestAdapter.ptfconfig: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/UnitTest/TestChecker.ptfconfig: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/UnitTest/TestInteractiveAdapter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using System; 3 | 4 | namespace Microsoft.Protocols.TestTools.UnitTest.TestAdapter 5 | { 6 | /// 7 | /// Interface definition of a interactive adapter 8 | /// 9 | public interface IInteractiveAdapter : IAdapter 10 | { 11 | [MethodHelp("Check interactive adapter return value, expected input value is [Y].")] 12 | int CheckReturnValueAfterEnterY(int number); 13 | 14 | [MethodHelp("Check interactive adapter return value, expected input value is [N].")] 15 | int CheckReturnValueAfterEnterN(int number); 16 | } 17 | 18 | /// 19 | /// Test cases to test PTF adapter: Interactive adapter 20 | /// 21 | [TestClass] 22 | public class TestInteractiveAdapter : TestClassBase 23 | { 24 | IInteractiveAdapter interactiveAdapter; 25 | 26 | [ClassInitialize] 27 | public static void ClassInitialize(TestContext testContext) 28 | { 29 | TestClassBase.Initialize(testContext, "TestAdapter"); 30 | } 31 | 32 | [ClassCleanup] 33 | public static void ClassCleanup() 34 | { 35 | TestClassBase.Cleanup(); 36 | } 37 | 38 | protected override void TestInitialize() 39 | { 40 | interactiveAdapter = BaseTestSite.GetAdapter(); 41 | } 42 | 43 | protected override void TestCleanup() 44 | { 45 | interactiveAdapter.Reset(); 46 | } 47 | 48 | #region Test cases 49 | [TestMethod] 50 | [TestCategory("TestAdapter")] 51 | public void InteractiveAdapterCheckReturnValueAfterEnterY() 52 | { 53 | int outValue = interactiveAdapter.CheckReturnValueAfterEnterY(0); 54 | BaseTestSite.Assert.AreEqual( 55 | 1, 56 | outValue, 57 | "Interactive adapter should return 1"); 58 | } 59 | 60 | [TestMethod] 61 | [TestCategory("TestAdapter")] 62 | [ExpectedException(typeof(AssertFailedException))] 63 | public void InteractiveAdapterCheckReturnValueAfterEnterN() 64 | { 65 | interactiveAdapter.CheckReturnValueAfterEnterN(0); 66 | } 67 | 68 | #endregion 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/UnitTest/TestLogging.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.IO; 6 | using Microsoft.Protocols.TestTools; 7 | using Microsoft.Protocols.TestTools.Logging; 8 | using Microsoft.Protocols.TestTools.UnitTest.Utilities; 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | 11 | namespace Microsoft.Protocols.TestTools.UnitTest.TestLogging 12 | { 13 | /// 14 | /// Defines a custom log sink. 15 | /// 16 | public class MySink : TextSink 17 | { 18 | StreamWriter sw; 19 | public MySink(string name) 20 | : base(name) 21 | { 22 | sw = new StreamWriter(String.Format("..\\..\\[TestLogging_MySinkLog]{0} MySinkLog.txt", DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff"))); 23 | } 24 | 25 | protected override TextWriter Writer 26 | { 27 | get { return sw; } 28 | } 29 | } 30 | 31 | 32 | /// 33 | /// Test cases to test PTF logging 34 | /// The cases do not verify if the generated log is expected. It should be done manually. 35 | /// 36 | [TestClass] 37 | public class TestLogging : TestClassBase 38 | { 39 | 40 | [ClassInitialize] 41 | public static void ClassInitialize(TestContext testContext) 42 | { 43 | TestClassBase.Initialize(testContext, "TestLogging"); 44 | } 45 | 46 | [ClassCleanup] 47 | public static void ClassCleanup() 48 | { 49 | TestClassBase.Cleanup(); 50 | } 51 | 52 | [TestCategory("TestLogging")] 53 | [TestMethod] 54 | public void AddGroupLog() 55 | { 56 | BaseTestSite.Log.Add(LogEntryKind.BeginGroup, "BeginGroup message"); 57 | BaseTestSite.Log.Add(LogEntryKind.EndGroup, "EndGroup message"); 58 | } 59 | 60 | [TestCategory("TestLogging")] 61 | [TestMethod] 62 | public void AddCheckpointLog() 63 | { 64 | BaseTestSite.Log.Add(LogEntryKind.Checkpoint, "Checkpoint message"); 65 | } 66 | 67 | [TestMethod] 68 | [TestCategory("TestLogging")] 69 | public void AddTestStepLog() 70 | { 71 | BaseTestSite.Log.Add(LogEntryKind.TestStep, "TestStep message"); 72 | } 73 | 74 | [TestMethod] 75 | [TestCategory("TestLogging")] 76 | public void AddCommentLog() 77 | { 78 | BaseTestSite.Log.Add(LogEntryKind.Comment, "Comment message"); 79 | } 80 | 81 | [TestMethod] 82 | [TestCategory("TestLogging")] 83 | public void AddWarningLog() 84 | { 85 | BaseTestSite.Log.Add(LogEntryKind.Warning, "Warning message"); 86 | } 87 | 88 | [TestMethod] 89 | [TestCategory("TestLogging")] 90 | public void AddDebugLog() 91 | { 92 | BaseTestSite.Log.Add(LogEntryKind.Debug, "Debug message"); 93 | } 94 | 95 | [TestMethod] 96 | [TestCategory("TestLogging")] 97 | public void AddMethodLog() 98 | { 99 | BaseTestSite.Log.Add(LogEntryKind.EnterMethod, "EnterMethod message"); 100 | BaseTestSite.Log.Add(LogEntryKind.ExitMethod, "ExitMethod message"); 101 | } 102 | 103 | [TestMethod] 104 | [TestCategory("TestLogging")] 105 | public void AddAdapterLog() 106 | { 107 | BaseTestSite.Log.Add(LogEntryKind.EnterAdapter, "EnterAdapter message"); 108 | BaseTestSite.Log.Add(LogEntryKind.ExitAdapter, "ExitAdapter message"); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/UnitTest/TestManagedAdapter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using Microsoft.Protocols.TestTools; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using Microsoft.Protocols.TestTools.UnitTest.Utilities; 8 | 9 | namespace Microsoft.Protocols.TestTools.UnitTest.TestAdapter 10 | { 11 | /// 12 | /// Interface definition of a managed adapter 13 | /// 14 | public interface IManagedAdapter : IAdapter 15 | { 16 | /// 17 | /// Adds two addends together 18 | /// 19 | int Sum(int x, int y); 20 | } 21 | 22 | public class ManagedAdapter : ManagedAdapterBase, IManagedAdapter 23 | { 24 | public int Sum(int x, int y) 25 | { 26 | return x + y; 27 | } 28 | } 29 | 30 | /// 31 | /// Interface definition of a managed adapter, but no relevant implementation 32 | /// 33 | public interface IUnimplementedManagedAdapter : IAdapter 34 | { 35 | /// 36 | /// Adds two addends together 37 | /// 38 | int Sum(int x, int y); 39 | } 40 | 41 | /// 42 | /// Test cases to test PTF adapter: Managed adapter 43 | /// 44 | [TestClass] 45 | public class TestManagedAdapter : TestClassBase 46 | { 47 | IManagedAdapter managedAdapter; 48 | 49 | [ClassInitialize] 50 | public static void ClassInitialize(TestContext testContext) 51 | { 52 | TestClassBase.Initialize(testContext, "TestAdapter"); 53 | } 54 | 55 | [ClassCleanup] 56 | public static void ClassCleanup() 57 | { 58 | TestClassBase.Cleanup(); 59 | } 60 | 61 | protected override void TestInitialize() 62 | { 63 | managedAdapter = BaseTestSite.GetAdapter(); 64 | } 65 | 66 | protected override void TestCleanup() 67 | { 68 | managedAdapter.Reset(); 69 | } 70 | 71 | #region Test cases 72 | [TestMethod] 73 | [TestCategory("TestAdapter")] 74 | public void ManagerAdapterCallSucceed() 75 | { 76 | BaseTestSite.Assert.AreEqual( 77 | 3 + 4, 78 | managedAdapter.Sum(3, 4), 79 | "Managed adapter should return 7"); 80 | } 81 | 82 | [TestMethod] 83 | [TestCategory("TestAdapter")] 84 | [PTFExpectedException(typeof(InvalidOperationException))] 85 | public void ManagerAdapterUnimplemented() 86 | { 87 | IUnimplementedManagedAdapter undefinedManagedAdapter = BaseTestSite.GetAdapter(); 88 | } 89 | #endregion 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/UnitTest/TestPowerShellAdapter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using Microsoft.Protocols.TestTools; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using Microsoft.Protocols.TestTools.UnitTest.Utilities; 8 | 9 | namespace Microsoft.Protocols.TestTools.UnitTest.TestAdapter 10 | { 11 | /// 12 | /// Interface definition of a powershell adapter 13 | /// 14 | public interface IPowershellAdapter : IAdapter 15 | { 16 | [MethodHelp("Powershell script will throw an exception.")] 17 | void ThrowException(string exceptionMessage); 18 | 19 | [MethodHelp("Powershell script will return an integer.")] 20 | int ReturnInt(int number); 21 | 22 | [MethodHelp("Test Powershell script will timeout to return.")] 23 | [InvokeTimeout(1)] 24 | int TestTimeout(int number); 25 | 26 | [MethodHelp("Powershell script will return a string.")] 27 | string ReturnString(string str); 28 | 29 | [MethodHelp("Powershell script will return a boolean.")] 30 | bool ReturnBool(bool value); 31 | 32 | [MethodHelp("The relevant Powershell script does not exist")] 33 | void ScriptNotExisted(); 34 | 35 | [MethodHelp("Powershell script will call another script and return a string.")] 36 | string NestedCall(string str); 37 | } 38 | 39 | /// 40 | /// Test cases to test PTF adapter: Powershell adapter 41 | /// 42 | [TestClass] 43 | public class TestPowershellAdapter : TestClassBase 44 | { 45 | IPowershellAdapter powershellAdapter; 46 | 47 | [ClassInitialize] 48 | public static void ClassInitialize(TestContext testContext) 49 | { 50 | TestClassBase.Initialize(testContext, "TestAdapter"); 51 | } 52 | 53 | [ClassCleanup] 54 | public static void ClassCleanup() 55 | { 56 | TestClassBase.Cleanup(); 57 | } 58 | 59 | protected override void TestInitialize() 60 | { 61 | powershellAdapter = BaseTestSite.GetAdapter(); 62 | } 63 | 64 | protected override void TestCleanup() 65 | { 66 | powershellAdapter.Reset(); 67 | } 68 | 69 | #region Test cases 70 | [TestMethod] 71 | [TestCategory("TestAdapter")] 72 | [PTFExpectedException(typeof(InvalidOperationException))] 73 | public void PowershellAdapterThrowException() 74 | { 75 | powershellAdapter.ThrowException("exception"); 76 | } 77 | 78 | [TestMethod] 79 | [TestCategory("TestAdapter")] 80 | public void PowershellAdapterReturnInt() 81 | { 82 | BaseTestSite.Assert.AreEqual( 83 | 0, 84 | powershellAdapter.ReturnInt(0), 85 | "Powershell adapter should return 0"); 86 | } 87 | 88 | [TestMethod] 89 | [TestCategory("TestAdapter")] 90 | [ExpectedException(typeof(TimeoutException))] 91 | public void PowershellAdapterTestTimeout() 92 | { 93 | powershellAdapter.TestTimeout(0); 94 | BaseTestSite.Assert.Fail("Invoke method call should timeout"); 95 | } 96 | 97 | [TestMethod] 98 | [TestCategory("TestAdapter")] 99 | public void PowershellAdpaterReturnString() 100 | { 101 | BaseTestSite.Assert.AreEqual( 102 | "PTF", 103 | powershellAdapter.ReturnString("PTF"), 104 | "Powershell adapter should return PTF"); 105 | } 106 | 107 | [TestMethod] 108 | [TestCategory("TestAdapter")] 109 | public void PowershellAdpaterReturnContainingSpecialCharaters() 110 | { 111 | string str = "It's great!!"; 112 | BaseTestSite.Assert.AreEqual( 113 | str, 114 | powershellAdapter.ReturnString(str), 115 | "Shell adapter should return " + str); 116 | } 117 | 118 | [TestMethod] 119 | [TestCategory("TestAdapter")] 120 | public void PowershellAdapterReturnBool() 121 | { 122 | BaseTestSite.Assert.IsTrue( 123 | powershellAdapter.ReturnBool(true), 124 | "Powershell adapter should return true"); 125 | } 126 | 127 | [TestMethod] 128 | [TestCategory("TestAdapter")] 129 | [PTFExpectedException(typeof(AssertInconclusiveException), "Assume.Fail failed. PowerShell script file (ScriptNotExisted.ps1) can not be found.")] 130 | public void PowershellAdapterScriptNotExisted() 131 | { 132 | powershellAdapter.ScriptNotExisted(); 133 | } 134 | 135 | [TestMethod] 136 | [TestCategory("TestAdapter")] 137 | public void PowershellAdapterNestedCall() 138 | { 139 | BaseTestSite.Assert.AreEqual( 140 | "PTF", 141 | powershellAdapter.NestedCall("PTF"), 142 | "Powershell adapter should return PTF"); 143 | } 144 | #endregion 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/UnitTest/TestProperties.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using Microsoft.Protocols.TestTools; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | 8 | namespace Microsoft.Protocols.TestTools.UnitTest.TestProperties 9 | { 10 | /// 11 | /// Test cases to test reading properties defined in .ptfconfig file 12 | /// 13 | [TestClass] 14 | public class TestProperties : TestClassBase 15 | { 16 | [ClassInitialize] 17 | public static void ClassInitialize(TestContext testContext) 18 | { 19 | TestClassBase.Initialize(testContext, "TestProperties"); 20 | } 21 | 22 | [ClassCleanup] 23 | public static void ClassCleanup() 24 | { 25 | TestClassBase.Cleanup(); 26 | } 27 | 28 | [TestMethod] 29 | [TestCategory("TestProperties")] 30 | public void ReadNormalProperty() 31 | { 32 | BaseTestSite.Assert.AreEqual( 33 | "NormalPropertyValue", 34 | BaseTestSite.Properties["NormalPropertyName"], 35 | "Value of property \"NormalPropertyName\" should be \"NormalPropertyValue\""); 36 | } 37 | 38 | [TestMethod] 39 | [TestCategory("TestProperties")] 40 | public void ReadDuplicateProperty() 41 | { 42 | BaseTestSite.Assert.AreEqual( 43 | "TestProperties", 44 | BaseTestSite.Properties["DuplicatePropertyName"], 45 | "Value of property \"DuplicatePropertyName\" should be \"TestProperties\""); 46 | } 47 | 48 | [TestMethod] 49 | [TestCategory("TestProperties")] 50 | public void ReadIncludedProperty() 51 | { 52 | BaseTestSite.Assert.AreEqual( 53 | "BasePropertyValue", 54 | BaseTestSite.Properties["BasePropertyName"], 55 | "Value of property \"BasePropertyName\" should be \"BasePropertyValue\""); 56 | } 57 | 58 | [TestMethod] 59 | [TestCategory("TestProperties")] 60 | public void ReadRootGroupProperty() 61 | { 62 | BaseTestSite.Assert.AreEqual( 63 | "RootPropertyValue", 64 | BaseTestSite.Properties["Root.Name"], 65 | "Value of property \"Root.Name\" should be \"RootPropertyValue\""); 66 | } 67 | 68 | [TestMethod] 69 | [TestCategory("TestProperties")] 70 | public void ReadLeafGroupProperty() 71 | { 72 | BaseTestSite.Assert.AreEqual( 73 | "LeafPropertyValue", 74 | BaseTestSite.Properties["Root.Leaf.Name"], 75 | "Value of property \"Root.Leaf.Name\" should be \"LeafPropertyValue\""); 76 | } 77 | 78 | [TestMethod] 79 | [TestCategory("TestProperties")] 80 | public void ReadEmptyProperty() 81 | { 82 | BaseTestSite.Assert.AreEqual( 83 | "", 84 | BaseTestSite.Properties[""], 85 | "Value of property \"\" should be \"\""); 86 | } 87 | 88 | [TestMethod] 89 | [TestCategory("TestProperties")] 90 | public void ReadDeploymentProperty() 91 | { 92 | BaseTestSite.Assert.AreEqual( 93 | "DeploymentPropertyValue", 94 | BaseTestSite.Properties["DeploymentPropertyName"], 95 | "Value of property \"DeploymentPropertyName\" should be \"DeploymentPropertyValue\""); 96 | } 97 | 98 | [TestMethod] 99 | [TestCategory("TestProperties")] 100 | public void ReadNonExistedProperty() 101 | { 102 | BaseTestSite.Assert.AreEqual( 103 | null, 104 | BaseTestSite.Properties["NonExistedProperty"], 105 | "Read a non existed property should return null"); 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/UnitTest/TestProperties.deployment.ptfconfig: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/UnitTest/TestProperties.ptfconfig: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/UnitTest/TestPtfTestClassBase.ptfconfig: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/UnitTest/TestRequirementCapture.ptfconfig: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/UnitTest/TestShellAdapter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using Microsoft.Protocols.TestTools; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using Microsoft.Protocols.TestTools.UnitTest.Utilities; 8 | 9 | namespace Microsoft.Protocols.TestTools.UnitTest.TestAdapter 10 | { 11 | public interface IShellAdapter : IAdapter 12 | { 13 | [MethodHelp("The script does not exist.")] 14 | void ScriptNotExisted(); 15 | 16 | [MethodHelp("Return the value of the property \"FeatureName\".")] 17 | string GetPtfProp(); 18 | 19 | [MethodHelp("Shell script will throw an exception.")] 20 | void ThrowException(string exceptionMessage); 21 | 22 | [MethodHelp("Shell script will return an integer.")] 23 | int ReturnInt(int number, out string name); 24 | 25 | [MethodHelp("Shell script will return a string.")] 26 | string ReturnString(string str); 27 | 28 | [MethodHelp("Shell script will return a boolean.")] 29 | bool ReturnBool(bool value); 30 | } 31 | 32 | /// 33 | /// Test cases to test PTF adapter: Script adapter 34 | /// 35 | [TestClass] 36 | public class TestShellAdapter : TestClassBase 37 | { 38 | IShellAdapter shellAdapter; 39 | 40 | [ClassInitialize] 41 | public static void ClassInitialize(TestContext testContext) 42 | { 43 | TestClassBase.Initialize(testContext, "TestAdapter"); 44 | } 45 | 46 | [ClassCleanup] 47 | public static void ClassCleanup() 48 | { 49 | TestClassBase.Cleanup(); 50 | } 51 | 52 | protected override void TestInitialize() 53 | { 54 | shellAdapter = BaseTestSite.GetAdapter(); 55 | } 56 | 57 | protected override void TestCleanup() 58 | { 59 | shellAdapter.Reset(); 60 | } 61 | 62 | #region Test cases 63 | [TestMethod] 64 | [TestCategory("TestAdapter")] 65 | [PTFExpectedException(typeof(AssertInconclusiveException), "Assume.Fail failed. Shell script file (ScriptNotExisted.sh) can not be found.")] 66 | public void ShellAdapterScriptNotExisted() 67 | { 68 | shellAdapter.ScriptNotExisted(); 69 | } 70 | 71 | [TestMethod] 72 | [TestCategory("TestAdapter")] 73 | public void ShellAdapterGetPtfProp() 74 | { 75 | string propName = "FeatureName"; 76 | BaseTestSite.Assert.AreEqual( 77 | BaseTestSite.Properties[propName], 78 | shellAdapter.GetPtfProp(), 79 | "Script adapter should return property value of {0}", propName); 80 | } 81 | 82 | [TestMethod] 83 | [TestCategory("TestAdapter")] 84 | [PTFExpectedException(typeof(InvalidOperationException))] 85 | public void ShellAdapterThrowException() 86 | { 87 | shellAdapter.ThrowException("Exception message."); 88 | } 89 | 90 | [TestMethod] 91 | [TestCategory("TestAdapter")] 92 | public void ShellAdapterReturnInt() 93 | { 94 | int num = 42; 95 | string name = string.Empty; 96 | BaseTestSite.Assert.AreEqual( 97 | num, 98 | shellAdapter.ReturnInt(num, out name), 99 | "Shell adapter should return " + num); 100 | } 101 | 102 | [TestMethod] 103 | [TestCategory("TestAdapter")] 104 | public void ShellAdpaterReturnString() 105 | { 106 | string str = "PTF"; 107 | BaseTestSite.Assert.AreEqual( 108 | str, 109 | shellAdapter.ReturnString(str), 110 | "Shell adapter should return " + str); 111 | } 112 | 113 | [TestMethod] 114 | [TestCategory("TestAdapter")] 115 | public void ShellAdapterReturnTrue() 116 | { 117 | BaseTestSite.Assert.IsTrue( 118 | shellAdapter.ReturnBool(true), 119 | "Shell adapter should return true"); 120 | } 121 | 122 | [TestMethod] 123 | [TestCategory("TestAdapter")] 124 | public void ShellAdapterReturnFalse() 125 | { 126 | BaseTestSite.Assert.IsFalse( 127 | shellAdapter.ReturnBool(false), 128 | "Shell adapter should return false"); 129 | } 130 | 131 | [TestMethod] 132 | [TestCategory("TestAdapter")] 133 | public void ShellAdpaterReturnStringContainingSpecialCharaters() 134 | { 135 | string str = "It's great!!"; 136 | BaseTestSite.Assert.AreEqual( 137 | str, 138 | shellAdapter.ReturnString(str), 139 | "Shell adapter should return " + str); 140 | } 141 | #endregion 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/UnitTest/UnitTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0;net7.0;net8.0 5 | false 6 | Microsoft.Protocols.TestTools.UnitTest 7 | Microsoft.Protocols.TestTools.UnitTest 8 | 9 | 10 | 11 | 12 | Always 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | PreserveNewest 39 | 40 | 41 | 42 | 43 | 44 | PreserveNewest 45 | 46 | 47 | 48 | 49 | 50 | PreserveNewest 51 | 52 | 53 | PreserveNewest 54 | 55 | 56 | PreserveNewest 57 | 58 | 59 | PreserveNewest 60 | 61 | 62 | PreserveNewest 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/UnitTest/Utilities/PTFExpectedException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using Microsoft.VisualStudio.TestTools.UnitTesting; 6 | 7 | namespace Microsoft.Protocols.TestTools.UnitTest.Utilities 8 | { 9 | /// 10 | /// An attrubite used for check if an expected exception is thrown in the case. 11 | /// It will check both exception type and message. 12 | /// 13 | public sealed class PTFExpectedException : ExpectedExceptionBaseAttribute 14 | { 15 | private Type ptfExpectedExceptionType; 16 | private string ptfExpectedExceptionMessage; 17 | 18 | public PTFExpectedException(Type expectedExceptionType) 19 | { 20 | ptfExpectedExceptionType = expectedExceptionType; 21 | ptfExpectedExceptionMessage = string.Empty; 22 | } 23 | 24 | public PTFExpectedException(Type expectedExceptionType, string expectedExceptionMessage) 25 | { 26 | ptfExpectedExceptionType = expectedExceptionType; 27 | ptfExpectedExceptionMessage = expectedExceptionMessage; 28 | } 29 | 30 | protected override void Verify(Exception exception) 31 | { 32 | Assert.IsNotNull(exception); 33 | 34 | Assert.IsInstanceOfType( 35 | exception, 36 | ptfExpectedExceptionType, 37 | "Wrong type of exception was thrown."); 38 | 39 | if (!ptfExpectedExceptionMessage.Length.Equals(0)) 40 | { 41 | int indexOfStackTrace = exception.Message.IndexOf("\r\n===== Stack Trace ====="); 42 | string getActualExceptionMessage = exception.Message.Substring(0, indexOfStackTrace); 43 | Assert.AreEqual( 44 | ptfExpectedExceptionMessage, getActualExceptionMessage, 45 | "Wrong exception message was returned."); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/UnitTest/Utilities/TestMakeStruct.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Protocols.TestTools.UnitTest.Utilities 5 | { 6 | public struct TestMakeStruct 7 | { 8 | public string TestValueString; 9 | 10 | public int TestValueInt; 11 | 12 | public bool TestValueBoolean; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/build.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft. All rights reserved. 2 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | $slnRoot = Split-Path -Parent $MyInvocation.MyCommand.Definition 5 | Push-Location $slnRoot 6 | if(Test-Path drop){ 7 | Remove-Item drop\* -Recurse -Force 8 | }else{ 9 | New-Item -ItemType Directory -Path drop 10 | } 11 | dotnet build .\TestFramework\TestFramework.csproj --configuration Release 12 | 13 | dotnet publish .\TestFramework\TestFramework.csproj -o drop -f net6.0 14 | 15 | dotnet publish .\TestFramework\TestFramework.csproj -o drop/net7 -f net7.0 16 | 17 | dotnet publish .\TestFramework\TestFramework.csproj -o drop/net8 -f net8.0 18 | 19 | nuget pack drop\TestFramework.nuspec 20 | $packageFile = [xml](Get-Content drop\TestFramework.nuspec) 21 | $assembly = $packageFile.package.metadata.id 22 | $version = $packageFile.package.metadata.version 23 | 24 | 25 | Copy-Item .\$assembly.$version.nupkg drop 26 | Pop-Location -------------------------------------------------------------------------------- /src/build.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft. All rights reserved. 2 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | slnRoot=$(pwd -P) 5 | 6 | # Create the folder, which will be used to store the final .nupkg file 7 | mkdir $slnRoot/../drop 8 | 9 | pushd $slnRoot/TestFramework 10 | 11 | csproj='TestFramework.csproj' 12 | assembly=$(awk -F "[><]" '/AssemblyName/{print $3}' $csproj) 13 | version=$(awk -F "[><]" '/Version/{print $3}' $csproj) 14 | 15 | # Build the nuget package 16 | dotnet clean --configuration Release 17 | dotnet pack --configuration Release 18 | 19 | # Copy the nuget package to drop folder 20 | cp ./bin/Release/$assembly.$version.nupkg $slnRoot/../drop/ 21 | 22 | popd 23 | --------------------------------------------------------------------------------