Skip to content

Commit 8f523f2

Browse files
authored
Merge pull request #4450 from fsprojects/test/migrate-legacy-tests
Migrate legacy-only tests to net10.0 ahead of the tool-only 12.0
2 parents 3dbebe5 + 479fe7e commit 8f523f2

25 files changed

Lines changed: 372 additions & 197 deletions

File tree

‎RELEASE_NOTES.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#### Unreleased
22

3+
* The `paket` .NET tool now honours `no_proxy` and the system proxy settings, as `paket.exe` already did; as in curl, a `no_proxy` entry matches the host and its subdomains
34

45
#### 11.0.0 - 2026-10-05
56

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
module Paket.IntegrationTests.DotnetToolSpecs
2+
3+
open System
4+
open System.IO
5+
open Fake
6+
open NUnit.Framework
7+
open FsUnit
8+
9+
// Paket.Restore.targets has to find the Paket .NET tool on its own: these tests install the
10+
// paket under test as a .NET tool and leave PaketExePath unset.
11+
12+
let scenario = "dotnet-tool-locator"
13+
14+
/// Restores the project of the scenario and checks that the installed tool did the Paket restore
15+
let restoreShouldUseTool version env =
16+
let scenarioPath = scenarioTempPath scenario
17+
let output =
18+
directDotnetEx env false "restore" (scenarioPath @@ "project")
19+
|> Seq.map (fun msg -> msg.Message)
20+
|> String.concat Environment.NewLine
21+
output |> shouldContainText $"Paket version %s{version}"
22+
File.Exists(scenarioPath @@ "paket-files" @@ "paket.restore.cached") |> shouldEqual true
23+
24+
/// Installs the packed tool into the scenario, at the location the arguments give
25+
let installTool env location =
26+
directDotnetEx env false $"tool install paket %s{location} --version %s{paketToolPackageVersion} --configfile nuget.config" (scenarioTempPath scenario)
27+
|> ignore
28+
29+
[<Test>]
30+
let ``restore finds paket as a local tool of the manifest``() =
31+
let cleanup, version, env = prepareSdkForTool scenario
32+
use __ = cleanup
33+
installTool env "--local"
34+
35+
restoreShouldUseTool version env
36+
37+
[<Test>]
38+
let ``restore finds paket installed with --tool-path .paket``() =
39+
let cleanup, version, env = prepareSdkForTool scenario
40+
use __ = cleanup
41+
installTool env "--tool-path .paket"
42+
43+
restoreShouldUseTool version env
44+
45+
[<Test>]
46+
let ``restore finds paket on the PATH like a global tool``() =
47+
let cleanup, version, env = prepareSdkForTool scenario
48+
use __ = cleanup
49+
let toolPath = scenarioTempPath scenario @@ "global-tools"
50+
installTool env $"--tool-path \"%s{toolPath}\""
51+
52+
let path = toolPath + string Path.PathSeparator + Environment.GetEnvironmentVariable "PATH"
53+
restoreShouldUseTool version (("PATH", path) :: env)

‎integrationtests/Paket.IntegrationTests/FrameworkRestrictionsSpecs.fs‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,8 @@ let ``#140 windsor should resolve framework dependent dependencies``() =
2020

2121
[<Test>]
2222
[<Flaky>] // failure on assert
23-
#if NO_UNIT_PLATFORMATTRIBUTE
24-
#else
25-
[<Platform("Mono")>] // PATH TOO LONG on Windows...
26-
#endif
2723
let ``#1190 paket add nuget should handle transitive dependencies``() =
24+
if Paket.Utils.isWindows then Assert.Ignore "PATH TOO LONG on Windows..."
2825
use __ = paket "add nuget xunit version 2.1.0" "i001190-transitive-dependencies-with-restr" |> fst
2926
let lockFile = LockFile.LoadFrom(Path.Combine(scenarioTempPath "i001190-transitive-dependencies-with-restr","paket.lock"))
3027
lockFile.Groups.[Constants.MainDependencyGroup].Resolution.[PackageName "xunit.abstractions"].Settings.FrameworkRestrictions

‎integrationtests/Paket.IntegrationTests/FsiExtension.fs‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ module FsiExtension =
2828
e.RequestingAssembly
2929
)
3030
let checker = FSharpChecker.Create(suggestNamesForErrors=true, keepAssemblyContents=true)
31+
// The package manager looks for a paket.dependencies from the folder of the script up.
32+
// A script inside the repository would pull in the one of Paket itself, whose github
33+
// dependencies hit the rate-limited api.github.com. The folder name stays fixed, since
34+
// the package manager keeps its work in a temp folder named after it.
35+
let scriptDir = Path.Combine(Path.GetTempPath(), "paket-fsi-extension-test")
36+
Directory.CreateDirectory scriptDir |> ignore
37+
let scriptPath = Path.Combine(scriptDir, "test.fsx")
3138
let sourceText = """
3239
#r "paket: nuget FSharp.Data"
3340
let v = FSharp.Data.JsonValue.Boolean true
@@ -36,7 +43,7 @@ module FsiExtension =
3643
// "--", not "/": the compiler only honours slash-prefixed options on Windows, since
3744
// elsewhere "/compilertool:..." is indistinguishable from a path. Passing them with a
3845
// slash on Linux left the paket package manager unregistered.
39-
checker.GetProjectOptionsFromScript("test.fsx", SourceText.ofString sourceText, otherFlags = [| "--langversion:preview"; $"--compilertool:%s{pathToExtension}" |] )
46+
checker.GetProjectOptionsFromScript(scriptPath, SourceText.ofString sourceText, otherFlags = [| "--langversion:preview"; $"--compilertool:%s{pathToExtension}" |] )
4047
|> Async.RunSynchronously
4148

4249
// Without this the `#r "paket:"` resolution failing shows up further down as an
@@ -48,7 +55,7 @@ module FsiExtension =
4855
|> String.concat Environment.NewLine
4956
|> failwithf "Resolving '#r \"paket: nuget FSharp.Data\"' through %s reported:%s%s" pathToExtension Environment.NewLine
5057

51-
let _, answer = checker.ParseAndCheckFileInProject("test.fsx", 0, SourceText.ofString sourceText, projectOptions) |> Async.RunSynchronously
58+
let _, answer = checker.ParseAndCheckFileInProject(scriptPath, 0, SourceText.ofString sourceText, projectOptions) |> Async.RunSynchronously
5259
match answer with
5360
| FSharpCheckFileAnswer.Succeeded(result) ->
5461
Assert.IsTrue result.HasFullTypeCheckInfo

‎integrationtests/Paket.IntegrationTests/InitSpecs.fs‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,25 @@ let ``#1040 init should download release version of bootstrapper``() =
2121
productVersion.Contains("-") |> shouldEqual false
2222

2323
[<Test>]
24-
#if PAKET_NETCORE
25-
[<Ignore(".net core paket doesnt init the boostrapper")>]
26-
#endif
2724
let ``#1743 empty log file``() =
2825
try
29-
use __ = paket "init --log-file" "i001040-init-downloads-bootstrapper" |> fst
26+
use __ = paket "init --log-file" "i001743-empty-log-file" |> fst
3027
failwith "expected error"
3128
with
3229
| ProcessFailedWithExitCode(_, _, msgs) ->
3330
(msgs.Errors |> Seq.head).Contains "--log-file"
3431
|> shouldEqual true
3532

33+
[<Test>]
34+
let ``init creates paket.dependencies``() =
35+
let scenario = "init-creates-dependencies-file"
36+
use __ = paket "init" scenario |> fst
37+
File.Exists(Path.Combine(scenarioTempPath scenario, "paket.dependencies")) |> shouldEqual true
38+
#if PAKET_NETCORE
39+
// only the legacy paket.exe downloads the bootstrapper into .paket
40+
File.Exists(Path.Combine(scenarioTempPath scenario, ".paket", "paket.exe")) |> shouldEqual false
41+
#endif
42+
3643
[<Test>]
3744
#if PAKET_NETCORE
3845
[<Ignore(".net core paket doesnt init the boostrapper")>]

‎integrationtests/Paket.IntegrationTests/OutdatedSpecs.fs‎

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,16 @@ let ``#183 outdated without params``() =
1616
msg |> shouldContainText "FSharp.Formatting 2.4 ->"
1717

1818
[<Test>]
19-
#if NO_UNIT_PLATFORMATTRIBUTE
20-
[<Ignore "PlatformAttribute not supported by netstandard NUnit">]
21-
#else
22-
[<Platform "Mono">] // PATH TOO LONG on Windows...
23-
#endif
2419
let ``#183 outdated --ignore-constraint``() =
20+
if Paket.Utils.isWindows then Assert.Ignore "PATH TOO LONG on Windows..."
2521
let cleanup, msg = paket "outdated --ignore-constraints" "i000183-outdated-with-special-parameters"
2622
use cleanup = cleanup
2723
msg.Contains("Newtonsoft.Json 6.0.7 -> 6.0.8") |> shouldEqual false
2824

2925

3026
[<Test>]
31-
#if NO_UNIT_PLATFORMATTRIBUTE
32-
[<Ignore "PlatformAttribute not supported by netstandard NUnit">]
33-
#else
34-
[<Platform "Mono">] // PATH TOO LONG on Windows...
35-
#endif
3627
let ``#183 outdated --include-prereleases``() =
28+
if Paket.Utils.isWindows then Assert.Ignore "PATH TOO LONG on Windows..."
3729
let cleanup, msg = paket "outdated --include-prereleases" "i000183-outdated-with-special-parameters"
3830
use cleanup = cleanup
3931
msg |> shouldContainText "Newtonsoft.Json 6.0.7 ->"

‎integrationtests/Paket.IntegrationTests/Paket.IntegrationTests.fsproj‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<TargetFrameworks>net461;net10.0</TargetFrameworks>
55
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
6-
<DefineConstants Condition=" '$(TargetFramework)' != 'net461'">PAKET_NETCORE;NO_UNIT_PLATFORMATTRIBUTE;TESTSUITE_KNOWN_FAILURE_DOTNETCORE_3005;FAKE_NETSTANDARD_API;@(DefineConstants)</DefineConstants>
6+
<DefineConstants Condition=" '$(TargetFramework)' != 'net461'">PAKET_NETCORE;@(DefineConstants)</DefineConstants>
77
</PropertyGroup>
88
<ItemGroup>
99
<Compile Include="FsiExtension.fs" />
@@ -23,6 +23,7 @@
2323
<Compile Include="PackSpecs.fs" />
2424
<Compile Include="InstallSpecs.fs" />
2525
<Compile Include="RestoreSpecs.fs" />
26+
<Compile Include="DotnetToolSpecs.fs" />
2627
<Compile Include="FrameworkRestrictionsSpecs.fs" />
2728
<Compile Include="HttpSpecs.fs" />
2829
<Compile Include="PaketCoreSpecs.fs" />

‎integrationtests/Paket.IntegrationTests/ResolverSkipsConflictsFastSpecs.fs‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,6 @@ let ``#2289 Paket 4.x install command takes hours to complete``() =
4141
|> shouldBeSmallerThan (SemVer.Parse "3.0")
4242

4343
[<Test>]
44-
#if NO_UNIT_PLATFORMATTRIBUTE
45-
[<Ignore "PlatformAttribute not supported by netstandard NUnit">]
46-
#else
47-
[<Platform("Net")>]
48-
#endif
4944
let ``#1174 Should find Ninject error``() =
5045
updateShouldFindPackageConflict "Ninject" "i001174-resolve-fast-conflict"
5146

‎integrationtests/Paket.IntegrationTests/RestoreSpecs.fs‎

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,8 @@ let ``#3012 Paket restore silently fails when TargetFramework(s) are specified i
134134
directDotnet false "build" projectDir |> ignore
135135

136136
[<Test>]
137-
#if NO_UNIT_PLATFORMATTRIBUTE
138-
[<Ignore "PlatformAttribute not supported by netstandard NUnit">]
139-
#else
140-
[<Platform "Win">] // read-only filesystem entries are really only a Windows thing
141-
#endif
142137
let ``#3410 Paket restore fails when obj files are readonly`` () =
138+
if not isWindows then Assert.Ignore "read-only filesystem entries are really only a Windows thing"
143139
let scenario = "i003410-readonly-obj"
144140
let projectName = "dotnet"
145141
let packageName = "AutoMapper"
@@ -162,7 +158,7 @@ let ``#3410 Paket restore fails when obj files are readonly`` () =
162158
cachedReferencesFile.IsReadOnly <- false
163159

164160
let private excludeAssetsForFSharpCore (propsPath: string) =
165-
let propsXml = System.Xml.Linq.XDocument.Load(System.IO.File.OpenRead propsPath)
161+
let propsXml = System.Xml.Linq.XDocument.Load propsPath
166162
let fsharpCorePackageRef =
167163
propsXml.Descendants()
168164
|> Seq.find (fun elem -> elem.Name.LocalName = "PackageReference")

‎integrationtests/Paket.IntegrationTests/TestHelper.fs‎

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ open NUnit.Framework
88
open FsUnit
99
open System
1010
open System.IO
11+
open System.IO.Compression
1112
open Paket.Logging
1213

1314
let disableScenarioCleanup = false // change to true to debug a single test temporarily.
@@ -86,19 +87,98 @@ let prepare scenario =
8687
if not (isNull shouldDispose) then shouldDispose.Dispose()
8788

8889

89-
let prepareSdk scenario =
90+
let private copyRestoreTargets scenario =
9091
let tmpPaketFolder = (scenarioTempPath scenario) @@ ".paket"
9192
let targetsFile = FullName(__SOURCE_DIRECTORY__ + "../../../src/Paket.Core/embedded/Paket.Restore.targets")
92-
let paketExe = snd paketToolPath
93-
94-
setEnvironVar "PaketExePath" paketExe
95-
let cleanup = prepare scenario
9693
if (not (Directory.Exists tmpPaketFolder)) then
9794
Directory.CreateDirectory tmpPaketFolder |> ignore
9895

9996
FileHelper.CopyFile tmpPaketFolder targetsFile
97+
98+
let prepareSdk scenario =
99+
let paketExe = snd paketToolPath
100+
101+
setEnvironVar "PaketExePath" paketExe
102+
let cleanup = prepare scenario
103+
copyRestoreTargets scenario
100104
cleanup
101105

106+
/// The version of the Paket tool package packTool makes. Any version does: the package is made
107+
/// again for each test, from the build under test, and installed into a scenario folder.
108+
let paketToolPackageVersion = "0.0.0-integrationtest"
109+
110+
/// Packs the paket of bin/net10.0 as a .NET tool into the folder, the way PackAsTool lays it out
111+
let private packTool folder =
112+
let toolDir = FullName(__SOURCE_DIRECTORY__ + "../../../bin/net10.0")
113+
Directory.CreateDirectory folder |> ignore
114+
use zip = ZipFile.Open(folder @@ $"Paket.%s{paketToolPackageVersion}.nupkg", ZipArchiveMode.Create)
115+
let addText (name:string) (text:string) =
116+
use writer = new StreamWriter(zip.CreateEntry(name).Open())
117+
writer.Write text
118+
addText "Paket.nuspec" (sprintf """<?xml version="1.0" encoding="utf-8"?>
119+
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
120+
<metadata>
121+
<id>Paket</id>
122+
<version>%s</version>
123+
<authors>Paket</authors>
124+
<description>The paket under test, packed as a .NET tool</description>
125+
<packageTypes>
126+
<packageType name="DotnetTool" />
127+
</packageTypes>
128+
</metadata>
129+
</package>
130+
""" paketToolPackageVersion)
131+
addText "tools/net10.0/any/DotnetToolSettings.xml" """<?xml version="1.0" encoding="utf-8"?>
132+
<DotNetCliTool Version="1">
133+
<Commands>
134+
<Command Name="paket" EntryPoint="paket.dll" Runner="dotnet" />
135+
</Commands>
136+
</DotNetCliTool>
137+
"""
138+
for file in Directory.GetFiles(toolDir, "*", SearchOption.AllDirectories) do
139+
let relativePath = file.Substring(toolDir.Length).TrimStart(Path.DirectorySeparatorChar).Replace('\\', '/')
140+
zip.CreateEntryFromFile(file, "tools/net10.0/any/" + relativePath) |> ignore
141+
142+
/// Like prepareSdk, but lets Paket.Restore.targets find paket on its own, the way it does
143+
/// for a user of the Paket .NET tool. Returns the cleanup, the full version of the paket
144+
/// under test (with its "+<commit>"), and the environment to run dotnet with.
145+
/// The tool is packed from bin/net10.0 into a feed of the scenario, the only source of its
146+
/// nuget.config, and installed into a packages folder of the scenario: the global one may
147+
/// hold a package of the same version.
148+
let prepareSdkForTool scenario =
149+
let productVersion =
150+
Diagnostics.FileVersionInfo.GetVersionInfo(FullName(__SOURCE_DIRECTORY__ + "../../../bin/net10.0/paket.dll")).ProductVersion
151+
152+
let cleanup = prepare scenario
153+
copyRestoreTargets scenario
154+
let scenarioPath = scenarioTempPath scenario
155+
let feed = scenarioPath @@ "tool-feed"
156+
packTool feed
157+
File.WriteAllText(
158+
scenarioPath @@ "nuget.config",
159+
sprintf """<?xml version="1.0" encoding="utf-8"?>
160+
<configuration>
161+
<packageSources>
162+
<clear />
163+
<add key="paket-build" value="%s" />
164+
</packageSources>
165+
</configuration>
166+
""" feed)
167+
// A manifest of its own, so that dotnet doesn't walk up to the one of the Paket repository,
168+
// neither to run `dotnet paket` nor to install a local tool
169+
Directory.CreateDirectory(scenarioPath @@ ".config") |> ignore
170+
File.WriteAllText(scenarioPath @@ ".config" @@ "dotnet-tools.json", """{ "version": 1, "isRoot": true, "tools": {} }""")
171+
172+
let env = [
173+
"NUGET_PACKAGES", scenarioPath @@ "nuget-packages"
174+
// prepareSdk sets it for the whole test process
175+
"PaketExePath", ""
176+
// The Linux CI sets it, and it makes the restore ask for Microsoft.WindowsDesktop.App.Ref,
177+
// which the feed of the scenario doesn't have
178+
"EnableWindowsTargeting", "false"
179+
]
180+
cleanup, productVersion, env
181+
102182
type OutputMsg =
103183
{ IsError : bool; Message : string }
104184
static member isError ({ IsError = e}:OutputMsg) = e

0 commit comments

Comments
 (0)