Skip to content

Commit 27a6f99

Browse files
Added Ci tests (#210)
1 parent 0fa6708 commit 27a6f99

37 files changed

+876
-682
lines changed

.gitattributes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# Misc
88
###############################################################################
99
*.psd1 text
10-
*.rc text eol=crlf encoding=utf-16le
10+
*.rc text eol=crlf encoding=UTF-8
1111
*.zip filter=lfs diff=lfs merge=lfs -text
1212

1313
###############################################################################

.github/workflows/autobuild.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ name: CI Build
22

33
permissions:
44
contents: read
5+
actions: read
6+
checks: write
57

68
on:
79
push:
@@ -67,6 +69,38 @@ jobs:
6769
run: |
6870
msbuild.exe DSInternals.Replication -target:Pack -property:Configuration=Debug -property:Platform=x64 -property:RestorePackages=false -property:NoBuild=true -property:BuildProjectReferences=false
6971
72+
- name: Run Unit Tests
73+
working-directory: Src
74+
run: |
75+
dotnet test DSInternals.TestsOnly.slnf --configuration Debug --no-build -- --report-trx --results-directory "${{ github.workspace }}/TestResults"
76+
77+
- name: Run PowerShell Desktop Tests
78+
working-directory: Scripts
79+
shell: powershell
80+
run: ./Invoke-SmokeTests.ps1 -Configuration 'Debug'
81+
82+
- name: Run PowerShell Core Tests
83+
working-directory: Scripts
84+
shell: pwsh
85+
run: ./Invoke-SmokeTests.ps1 -Configuration 'Debug'
86+
87+
- name: Upload Test Results as Artifact
88+
if: ${{ !cancelled() }}
89+
uses: actions/upload-artifact@v4
90+
with:
91+
name: TestResults
92+
path: TestResults/*
93+
94+
- name: Generate Unit Test Report
95+
uses: dorny/test-reporter@v2
96+
if: ${{ !cancelled() }}
97+
with:
98+
name: MSTest
99+
reporter: dotnet-trx
100+
path: TestResults/*.trx
101+
use-actions-summary: true
102+
badge-title: Unit Tests
103+
70104
- name: Get PowerShell Module Version
71105
shell: pwsh
72106
id: get-module-version

.github/workflows/release.yml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,20 @@ jobs:
234234
with:
235235
name: NuGet_v${{ steps.get-module-info.outputs.version }}
236236
path: Build/package/release/*nupkg
237-
238-
# TODO: Smoke Tests
237+
238+
- name: Run PowerShell Desktop Tests
239+
working-directory: Scripts
240+
shell: powershell
241+
run: ./Invoke-SmokeTests.ps1 -Configuration 'Release'
242+
243+
- name: Run PowerShell Core Tests
244+
working-directory: Scripts
245+
shell: pwsh
246+
run: ./Invoke-SmokeTests.ps1 -Configuration 'Release'
247+
248+
- name: Test Module Digital Signatures
249+
shell: powershell
250+
run: ./Build/bin/DSInternals.PowerShell/Release/DSInternals/Integrity.Tests.ps1
239251

240252
nuget:
241253
name: 'Publish to NuGet Gallery'

Scripts/Invoke-SmokeTests.ps1

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,47 @@
11
<#
22
.SYNOPSIS
3-
The purpose of this script is to check the Release build for any obvious flaws without running all unit tests.
3+
The purpose of this script is to check the PowerShell module for any obvious flaws.
44
#>
55

6-
#Requires -Version 5
6+
#Requires -Version 5.1
77
#Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' }
88

9+
param(
10+
[Parameter(Mandatory = $false)]
11+
[ValidateSet('Release', 'Debug')]
12+
[string] $Configuration = 'Release'
13+
)
14+
915
[string] $root = Split-Path -Path $PSScriptRoot -Parent
10-
[string] $dsInternalsModulePath = Join-Path -Path $root -ChildPath 'Build\bin\DSInternals.PowerShell\Release\DSInternals'
16+
[string] $dsInternalsModulePath = Join-Path -Path $root -ChildPath "Build\bin\DSInternals.PowerShell\$Configuration\DSInternals"
1117

1218
[string] $testsPath = Join-Path -Path $root -ChildPath 'Src\DSInternals.PowerShell\Tests\'
1319
[string] $resultsPath = Join-Path -Path $root -ChildPath 'TestResults'
14-
[string] $docPath = Join-Path -Path $root -ChildPath 'Documentation'
15-
[string] $nuspecPath = Join-Path -Path $root -ChildPath 'Src\DSInternals.PowerShell\Chocolatey\*.nuspec' -Resolve
1620

1721
# Create output dir if it does not exist
1822
New-Item -Path $resultsPath -ItemType Directory -Force | Out-Null
1923

20-
Import-Module -Name Pester
24+
# Re-import the compiled DSInternals module
25+
Remove-Module -Name DSInternals -ErrorAction SilentlyContinue
26+
Import-Module -Name $dsInternalsModulePath -Force -ErrorAction Stop
2127

22-
# Prepare test options
23-
[Pester.ContainerInfo] $testParams = New-PesterContainer -Path "$testsPath\*.Smoke.Tests.ps1" -Data @{
24-
ModulePath = $dsInternalsModulePath;
25-
MarkdownDocumentationPath = $docPath;
26-
ChocolateySpecPath = $nuspecPath
27-
}
28+
# Import the Pester module to make the PesterConfiguration type available.
29+
Import-Module -Name Pester -ErrorAction Stop
2830

31+
# Example: Pester-Smoke-Release-Desktop.xml
32+
[string] $resultsFileName = 'Pester-Smoke-{0}-{1}.xml' -f $Configuration,$PSVersionTable.PSEdition
33+
[string] $resultsFilePath = Join-Path -Path $resultsPath -ChildPath $resultsFileName
34+
35+
# Prepare test options
2936
[PesterConfiguration] $testConfig = New-PesterConfiguration
30-
$testConfig.Run.Container = $testParams
37+
$testConfig.Run.Path = $testsPath
38+
$testConfig.Run.Container = New-PesterContainer -Path $testsPath -Data @{
39+
Configuration = $Configuration
40+
}
3141
$testConfig.Output.Verbosity = 'Detailed'
3242
$testConfig.TestResult.Enabled = $true
3343
$testConfig.TestResult.OutputFormat = 'NUnitXml'
34-
$testConfig.TestResult.OutputPath = "$resultsPath\SmokeTests.xml"
44+
$testConfig.TestResult.OutputPath = $resultsFilePath
3545
$testConfig.Run.Exit = $true
3646
$testConfig.Run.PassThru = $false
3747

Scripts/Publish-PSModule.ps1

Lines changed: 0 additions & 24 deletions
This file was deleted.

Scripts/Update-PSHelp.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ Refreshes MD documentation files and builds MAML files.
66
Przemysław Kłys (@PrzemyslawKlys)
77
#>
88

9-
#Requires -Version 5 -Module platyPS
9+
#Requires -Version 5.1
10+
#Requires -Modules platyPS
1011

1112
# Set directory paths
1213
[string] $rootDir = Split-Path $PSScriptRoot -Parent

Src/DSInternals.Common/Validator.cs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
using System;
2-
using System.ComponentModel;
3-
using System.DirectoryServices.ActiveDirectory;
4-
using System.IO;
1+
using System.ComponentModel;
2+
using System.Net.Sockets;
53
using System.Security;
64
using DSInternals.Common.Cryptography;
75
using DSInternals.Common.Exceptions;
@@ -20,7 +18,7 @@ public static void AssertSuccess(NtStatus status)
2018

2119
internal static void AssertSuccess(NTSTATUS status)
2220
{
23-
if(status.SeverityCode == NTSTATUS.Severity.Success)
21+
if (status.SeverityCode == NTSTATUS.Severity.Success)
2422
{
2523
// No error has occured
2624
return;
@@ -38,7 +36,7 @@ internal static void AssertSuccess(NTSTATUS status)
3836

3937
public static void AssertSuccess(Win32ErrorCode code)
4038
{
41-
switch(code)
39+
switch (code)
4240
{
4341
case Win32ErrorCode.Success:
4442
case Win32ErrorCode.MORE_DATA:
@@ -49,7 +47,7 @@ public static void AssertSuccess(Win32ErrorCode code)
4947
var genericException = new Win32Exception((int)code);
5048
Exception exceptionToThrow;
5149
// We will try to translate the generic Win32 exception to a more specific built-in exception.
52-
switch(code)
50+
switch (code)
5351
{
5452
case Win32ErrorCode.DS_INVALID_DN_SYNTAX:
5553
case Win32ErrorCode.INVALID_PARAMETER:
@@ -74,7 +72,7 @@ public static void AssertSuccess(Win32ErrorCode code)
7472
case Win32ErrorCode.NO_SUCH_DOMAIN:
7573
case Win32ErrorCode.RPC_S_SERVER_UNAVAILABLE:
7674
case Win32ErrorCode.RPC_S_CALL_FAILED:
77-
exceptionToThrow = new ActiveDirectoryServerDownException(genericException.Message, genericException);
75+
exceptionToThrow = new SocketException((int)code);
7876
break;
7977
case Win32ErrorCode.DS_OBJ_NOT_FOUND:
8078
// This error code means either a non-existing DN or Access Denied.
@@ -92,9 +90,9 @@ public static void AssertSuccess(Win32ErrorCode code)
9290

9391
public static void AssertEquals(string expectedValue, string actualValue, string paramName)
9492
{
95-
if(!String.Equals(expectedValue, actualValue, StringComparison.InvariantCulture))
93+
if (!String.Equals(expectedValue, actualValue, StringComparison.InvariantCulture))
9694
{
97-
string message = String.Format("The input contains an unexpected value '{0}', while the expected value is '{1}'.", actualValue, expectedValue);
95+
string message = String.Format("The input contains an unexpected value '{0}', while the expected value is '{1}'.", actualValue, expectedValue);
9896
throw new ArgumentException(message, paramName);
9997
}
10098
}
@@ -119,7 +117,7 @@ public static void AssertEquals(char expectedValue, char actualValue, string par
119117

120118
public static void AssertNotNull(object value, string paramName)
121119
{
122-
if(value == null)
120+
if (value == null)
123121
{
124122
throw new ArgumentNullException(paramName);
125123
}
@@ -135,7 +133,7 @@ public static void AssertNotNullOrEmpty(string value, string paramName)
135133

136134
public static void AssertNotNullOrWhiteSpace(string value, string paramName)
137135
{
138-
if(string.IsNullOrWhiteSpace(value))
136+
if (string.IsNullOrWhiteSpace(value))
139137
{
140138
throw new ArgumentNullException(paramName);
141139
}
@@ -144,7 +142,7 @@ public static void AssertNotNullOrWhiteSpace(string value, string paramName)
144142
public static void AssertLength(string value, int length, string paramName)
145143
{
146144
AssertNotNull(value, paramName);
147-
if(value.Length != length)
145+
if (value.Length != length)
148146
{
149147
throw new ArgumentOutOfRangeException(paramName, value.Length, "The length of the input is unexpected.");
150148
}
@@ -218,7 +216,7 @@ public static void AssertLength(byte[] value, long length, string paramName)
218216
public static void AssertFileExists(string filePath)
219217
{
220218
bool exists = File.Exists(filePath);
221-
if(!exists)
219+
if (!exists)
222220
{
223221
throw new FileNotFoundException("Path not found.", filePath);
224222
}
@@ -236,7 +234,7 @@ public static void AssertDirectoryExists(string directoryPath)
236234
public static void AssertCrcMatches(byte[] buffer, uint expectedCrc)
237235
{
238236
uint actualCrc = Crc32.Calculate(buffer);
239-
if(actualCrc != expectedCrc)
237+
if (actualCrc != expectedCrc)
240238
{
241239
throw new FormatException("CRC check failed.");
242240
}

Src/DSInternals.PowerShell/Chocolatey/dsinternals-psmodule.nuspec

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
44
<metadata>
55
<id>DSInternals-PSModule</id>
6-
<version>6.0</version>
6+
<version>6.1</version>
77
<packageSourceUrl>https://github.com/MichaelGrafnetter/DSInternals/tree/master/Src/DSInternals.PowerShell/Chocolatey</packageSourceUrl>
88
<owners>MichaelGrafnetter</owners>
99
<title>DSInternals PowerShell Module</title>
@@ -37,11 +37,10 @@ The DSInternals PowerShell Module has these main features:
3737
## Disclaimer
3838
Features exposed through these tools are not supported by Microsoft. Improper use might cause irreversible damage to domain controllers or negatively impact domain security.</description>
3939
<releaseNotes>
40-
* Implemented support for PowerShell Core 7 on Windows.
41-
* The new Get-ADDBTrust cmdlet can read inter-domain trust objects from ntds.dit files, decrypt the trust passwords, and derive the Kerberos trust keys.
42-
* Added the Get-ADReplKdsRootKey cmdlet to enable reading specific KDS Root Keys over the MS-DRSR protocol.
43-
* Implemented full support for ntds.dit files originating from RODCs.
44-
* Improved the performance of schema loading and account retrieval from ntds.dit files.
40+
* Fixed a bug in `ntds.dit` prefix table parsing.
41+
* Re-enabled native ARM64 support.
42+
* Fixed RSA public key operation issues in PowerShell Core.
43+
* Added the `Integrity.Tests.ps1` script for checking module integrity.
4544
</releaseNotes>
4645
<dependencies>
4746
<!-- Windows Management Framework 3+. For OS prior to Windows 8 and Windows Server 2012. -->

Src/DSInternals.PowerShell/DSInternals.psd1

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ FileList = @(
176176
'DSInternals.types.ps1xml',
177177
'License.txt',
178178
'en-US\about_DSInternals.help.txt',
179-
'en-US\DSInternals.PowerShell.dll-Help.xml'
179+
'en-US\DSInternals.PowerShell.dll-Help.xml',
180+
'net48\DSInternals.Common.dll',
180181
'net48\DSInternals.DataStore.dll',
181182
'net48\DSInternals.Replication.dll',
182183
'net48\DSInternals.Replication.Model.dll',
@@ -202,6 +203,7 @@ FileList = @(
202203
'net8.0-windows\DSInternals.DataStore.dll',
203204
'net8.0-windows\DSInternals.Replication.dll',
204205
'net8.0-windows\DSInternals.Replication.Model.dll',
206+
'net8.0-windows\DSInternals.Common.dll',
205207
'net8.0-windows\DSInternals.SAM.dll',
206208
'net8.0-windows\amd64\DSInternals.Replication.Interop.dll',
207209
'net8.0-windows\arm64\DSInternals.Replication.Interop.dll',

Src/DSInternals.PowerShell/Integrity.Tests.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ Describe 'DSInternals PowerShell Module Integrity' {
103103
catch [System.BadImageFormatException] {
104104
# This DLL file is not a .NET assembly, so the test is not applicable.
105105
# Such files include the Microsoft C++ runtime libraries.
106-
Set-ItResult -Skipped -Because 'File is not a .NET assembly.'
106+
Set-ItResult -Skipped -Because 'this file is not a .NET assembly.'
107107
}
108108
}
109109

@@ -118,7 +118,7 @@ Describe 'DSInternals PowerShell Module Integrity' {
118118
)
119119

120120
if ($FileName -in $unsignedFiles) {
121-
Set-ItResult -Skipped -Because 'File is not signed by its vendor.'
121+
Set-ItResult -Skipped -Because 'this file is not signed by its vendor.'
122122
return
123123
}
124124

0 commit comments

Comments
 (0)