├── .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