Skip to content

Commit 773e1cb

Browse files
CSHARP-2933: Packaging tests.
1 parent 0e0400c commit 773e1cb

File tree

2 files changed

+293
-0
lines changed

2 files changed

+293
-0
lines changed

build.cake

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ var testsDirectory = solutionDirectory.Combine("tests");
2929
var outputDirectory = solutionDirectory.Combine("build");
3030
var toolsDirectory = solutionDirectory.Combine("tools");
3131
var toolsHugoDirectory = toolsDirectory.Combine("Hugo");
32+
var artifactsPackagingTestsDirectory = artifactsDirectory.Combine("Packaging.Tests");
33+
var localNugetSourceName = "LocalPackages";
34+
var mongoDbDriverPackageName = "MongoDB.Driver";
3235

3336
var solutionFile = solutionDirectory.CombineWithFilePath("CSharpDriver.sln");
3437
var solutionFullPath = solutionFile.FullPath;
@@ -562,6 +565,212 @@ Task("DumpGitVersion")
562565
Information(gitVersion.Dump());
563566
});
564567

568+
Task("PreparePackagingTests")
569+
.Does(() =>
570+
{
571+
var nugetConfigPath = artifactsDirectory.CombineWithFilePath("nuget.config");
572+
if (FileExists(nugetConfigPath)) DeleteFile(nugetConfigPath);
573+
574+
CreateNugetConfig(nugetConfigPath);
575+
576+
void CreateNugetConfig(FilePath filePath)
577+
{
578+
DotNetCoreTool(filePath, "new nugetconfig"); // create a default nuget.config
579+
580+
// <packageSources>
581+
// <add key="{localNugetSourceName}" value="packages" />
582+
// </packageSources>
583+
XmlPoke(filePath, "/configuration/packageSources/add/@key", $"{localNugetSourceName}");
584+
XmlPoke(filePath, $"/configuration/packageSources/add[@key = '{localNugetSourceName}']/@value", "packages");
585+
}
586+
});
587+
588+
Task("PackagingProjectReferenceTests")
589+
.IsDependentOn("Build")
590+
.DoesForEach(
591+
GetFiles("./**/*.Tests.csproj"),
592+
testProject =>
593+
{
594+
var settings = new DotNetCoreTestSettings
595+
{
596+
NoBuild = true,
597+
NoRestore = true,
598+
Configuration = configuration,
599+
ArgumentCustomization = args => args.Append("-- RunConfiguration.TargetPlatform=x64"),
600+
Filter = "Category=\"Packaging\""
601+
};
602+
603+
DotNetCoreTest(
604+
testProject.FullPath,
605+
settings
606+
);
607+
});
608+
609+
Task("PackagingTests")
610+
.IsDependentOn("PackagingProjectReferenceTests")
611+
.IsDependentOn("Package")
612+
.IsDependentOn("PreparePackagingTests")
613+
.DoesForEach(
614+
() =>
615+
{
616+
var packagesList = NuGetList(
617+
new NuGetListSettings {
618+
AllVersions = true,
619+
Prerelease = true,
620+
Source = new [] { $"{localNugetSourceName}" }, // corresponds to artifacts Nuget.config
621+
WorkingDirectory = artifactsDirectory
622+
});
623+
624+
foreach(var package in packagesList)
625+
{
626+
Information("Found packages {0}, version {1}", package.Name, package.Version);
627+
}
628+
if (packagesList.Count(p => p.Name == mongoDbDriverPackageName) != 1)
629+
{
630+
throw new Exception($"Package {mongoDbDriverPackageName} must be presented and unique.");
631+
}
632+
var mongoDriverPackageVersion = packagesList.Single(p => p.Name == mongoDbDriverPackageName).Version;
633+
Information($"Package version {mongoDriverPackageVersion}");
634+
635+
var testDetails = new List<(string Moniker, string CsprojType, string Version, string Bitness, string Command)>
636+
{
637+
/* Should be considered in https://jira.mongodb.org/browse/CSHARP-3805
638+
{ ("v4.7.2", "NonSdk", mongoDriverPackageVersion) }, */
639+
640+
{ ("net472", "SDK", mongoDriverPackageVersion, "x64", Command: "xunit") }, // TODO: add x32
641+
{ ("netcoreapp21", "SDK", mongoDriverPackageVersion, "x64", Command: "xunit") },
642+
{ ("netcoreapp30", "SDK", mongoDriverPackageVersion, "x64", Command: "xunit") },
643+
{ ("net50", "SDK", mongoDriverPackageVersion, "x64", Command: "xunit") }
644+
};
645+
646+
// run the same tests on console app
647+
testDetails.AddRange(testDetails.ToArray().Select(i => (i.Moniker, i.CsprojType, i.Version, i.Bitness, Command: "console")));
648+
649+
return testDetails;
650+
},
651+
(testDetails) =>
652+
{
653+
var moniker = testDetails.Moniker;
654+
var csprojFormat = testDetails.CsprojType;
655+
var mongoDriverPackageVersion = testDetails.Version;
656+
var command = testDetails.Command;
657+
658+
Information($"Moniker: {moniker}, csproj style: {csprojFormat}");
659+
660+
var monikerTestFolder = artifactsPackagingTestsDirectory.Combine($"{moniker}_{csprojFormat}_{command}");
661+
Information($"Moniker test folder: {monikerTestFolder}");
662+
EnsureDirectoryExists(monikerTestFolder);
663+
CleanDirectory(monikerTestFolder);
664+
665+
var csprojFileName = $"{monikerTestFolder.GetDirectoryName()}.csproj";
666+
var csprojFullPath = monikerTestFolder.CombineWithFilePath(csprojFileName);
667+
668+
switch (command)
669+
{
670+
case "xunit":
671+
{
672+
if (moniker == "net472")
673+
{
674+
// CSHARP-3806
675+
return;
676+
}
677+
678+
Information("Creating test project...");
679+
DotNetCoreTool(csprojFullPath, "new xunit", $"--target-framework-override {moniker} --language C# ");
680+
Information("Created test project");
681+
682+
Information($"Adding FluentAssertions...");
683+
DotNetCoreTool(
684+
csprojFullPath,
685+
"add package FluentAssertions",
686+
$"--framework {moniker} --version 4.12.0"
687+
);
688+
Information($"Added FluentAssertions");
689+
690+
Information($"Adding test package...");
691+
DotNetCoreTool(
692+
csprojFullPath,
693+
$"add package {mongoDbDriverPackageName}",
694+
$"--framework {moniker} --version {mongoDriverPackageVersion}"
695+
);
696+
Information("Added tested package");
697+
698+
DeleteFile(monikerTestFolder.CombineWithFilePath("UnitTest1.cs")); // Remove a default unit test
699+
var packagingTestsDirectory = testsDirectory.Combine("MongoDB.Driver.Tests").Combine("Packaging");
700+
Console.WriteLine($"Original test file {packagingTestsDirectory}");
701+
var files = GetFiles($"{packagingTestsDirectory}/*.cs").ToList();
702+
CopyFiles(files, monikerTestFolder); // copy tests content
703+
704+
Information("Running tests...");
705+
DotNetCoreTest(
706+
csprojFullPath.ToString(),
707+
new DotNetCoreTestSettings
708+
{
709+
Framework = moniker,
710+
Configuration = configuration,
711+
ArgumentCustomization = args => args.Append($"-- RunConfiguration.TargetPlatform={testDetails.Bitness}")
712+
}
713+
);
714+
}
715+
break;
716+
case "console":
717+
{
718+
Information("Creating console project...");
719+
DotNetCoreTool(csprojFullPath, "new console", $"--target-framework-override {moniker} --language C# ");
720+
Information("Created test project");
721+
722+
Information($"Adding tested package...");
723+
DotNetCoreTool(
724+
csprojFullPath,
725+
$"add package {mongoDbDriverPackageName}",
726+
$"--framework {moniker} --version {mongoDriverPackageVersion}"
727+
);
728+
Information("Added test package");
729+
730+
// the below two packages are added just to allow using the same code as in xunit
731+
Information($"Adding FluentAssertions...");
732+
DotNetCoreTool(
733+
csprojFullPath,
734+
"add package FluentAssertions",
735+
$"--framework {moniker} --version 4.12.0"
736+
);
737+
Information($"Added FluentAssertions");
738+
739+
Information($"Adding xunit...");
740+
DotNetCoreTool(
741+
csprojFullPath,
742+
"add package xunit",
743+
$"--framework {moniker} --version 2.4.0"
744+
);
745+
Information($"Added xunit");
746+
747+
DeleteFile(monikerTestFolder.CombineWithFilePath("Program.cs")); // Remove a default .cs file
748+
var packagingTestsDirectory = testsDirectory.Combine("MongoDB.Driver.Tests").Combine("Packaging");
749+
Console.WriteLine($"Original test file {packagingTestsDirectory}");
750+
var files = GetFiles($"{packagingTestsDirectory}/*.cs").ToList();
751+
CopyFiles(files, monikerTestFolder); // copy tests content
752+
753+
Information("Running console app...");
754+
DotNetCoreRun(
755+
csprojFullPath.ToString(),
756+
new DotNetCoreRunSettings
757+
{
758+
EnvironmentVariables = new Dictionary<string, string>()
759+
{
760+
{ "DefineConstants", "CONSOLE_TEST" }
761+
},
762+
Framework = moniker,
763+
Configuration = configuration,
764+
ArgumentCustomization = args => args.Append($"-- RunConfiguration.TargetPlatform={testDetails.Bitness}")
765+
}
766+
);
767+
}
768+
break;
769+
default: throw new NotSupportedException($"Packaging tests for {testDetails.Command} is not supported.");
770+
}
771+
})
772+
.DeferOnError();
773+
565774
RunTarget(target);
566775

567776
void ThrowIfNotDefaultTarget(string @value)
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/* Copyright 2021-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
// this directive is configured/used only in cake packaging tests
17+
#if CONSOLE_TEST
18+
using System;
19+
#endif
20+
using System.Reflection;
21+
using FluentAssertions;
22+
using MongoDB.Libmongocrypt;
23+
using Xunit;
24+
25+
namespace MongoDB.Driver.Tests.Packaging
26+
{
27+
/// <summary>
28+
/// Be aware that this test file will be also called from packaging script-based tests that don't have references on our test helpers.
29+
/// So, don't add any complex tests here other than simple smoke ones that only validate that a required native library is available.
30+
/// Also, use only public classes or reflection here.
31+
/// </summary>
32+
[Trait("Category", "Packaging")]
33+
public class PackagingTests
34+
{
35+
// keep these tests in sync with CONSOLE_TEST's Main method
36+
[Fact]
37+
public static void Libmongocrypt_library_should_provide_library_version()
38+
{
39+
Library.Version.Should().Be("1.2.1");
40+
}
41+
42+
[Fact]
43+
public static void Zstandard_compression_should_provide_MaxCompressionLevel()
44+
{
45+
var result = GetStaticFieldValue<int>(
46+
assemblyName: "MongoDB.Driver.Core",
47+
className: "MongoDB.Driver.Core.Compression.Zstandard.ZstandardNativeWrapper",
48+
fieldName: "MaxCompressionLevel");
49+
50+
result.Should().Be(22);
51+
}
52+
53+
// private methods
54+
private static T GetStaticFieldValue<T>(string assemblyName, string className, string fieldName)
55+
{
56+
var assembly = Assembly.Load(new AssemblyName(assemblyName));
57+
var @class = assembly.GetType(className, throwOnError: true).GetTypeInfo();
58+
var property = @class.GetProperty(fieldName, BindingFlags.Public | BindingFlags.Static);
59+
return (T)property.GetValue(null);
60+
}
61+
62+
private static T InvokeStaticMethod<T>(string assemblyName, string className, string methodName, params object[] arguments)
63+
{
64+
var assembly = Assembly.Load(new AssemblyName(assemblyName));
65+
var @class = assembly.GetType(className, throwOnError: true).GetTypeInfo();
66+
var method = @class.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static);
67+
return (T)method.Invoke(null, arguments);
68+
}
69+
70+
#if CONSOLE_TEST
71+
static void Main(string[] args)
72+
{
73+
Libmongocrypt_library_should_provide_library_version();
74+
75+
Zstandard_compression_should_provide_MaxCompressionLevel();
76+
77+
var defaultForegroundColor = Console.ForegroundColor;
78+
Console.ForegroundColor = ConsoleColor.Green;
79+
Console.WriteLine("\nAll packaging tests passed.");
80+
Console.ForegroundColor = defaultForegroundColor;
81+
}
82+
#endif
83+
}
84+
}

0 commit comments

Comments
 (0)