Finishing What We Started
The Vagrant WSL2 provider had a test/integration_old/todos/ folder with unimplemented tests. Two big ones: test_provisioners.ps1 and test_docker.ps1. Both just had TODO comments saying what they should test.
We’d already migrated the working tests to Pester 5.x format. The old homegrown PowerShell scripts worked fine - they just weren’t using a framework. Now we needed to implement these missing tests using the same Pester patterns.
Provisioners: One Monolith, Five Tests
The examples/provisioners/ directory had one massive Vagrantfile testing shell, file, ansible, chef, and salt provisioners all at once. To test them individually, we needed to split them up.
Created a subfolder for each provisioner:
examples/provisioners/
├── shell/
│ └── Vagrantfile
├── file/
│ ├── Vagrantfile
│ └── test-file.txt
├── ansible/
│ ├── Vagrantfile
│ └── test-playbook.yml
├── chef/
│ ├── Vagrantfile
│ └── cookbooks/
└── salt/
├── Vagrantfile
└── states/
Each subfolder has its own self-contained Vagrantfile that demonstrates one provisioner. This makes them usable as examples and testable individually.
Provisioners.Tests.ps1
The Pester test defines separate Describe blocks for each provisioner:
# Provisioners.Tests.ps1
param([switch]$Full)
Describe "Vagrant WSL2 Provider - Shell Provisioner" {
BeforeAll {
$script:ExampleDir = Join-Path $PSScriptRoot "..\..\examples\provisioners\shell"
$script:DistributionName = "vagrant-wsl2-shell-test"
Push-Location $script:ExampleDir
vagrant destroy -f 2>$null | Out-Null
}
AfterAll {
vagrant destroy -f 2>$null | Out-Null
Pop-Location
}
Context "When provisioning with shell scripts" {
It "Should successfully run 'vagrant up --provider=wsl2'" {
vagrant up --provider=wsl2
$LASTEXITCODE | Should -Be 0
}
It "Should have created shell-test.txt file" {
$result = vagrant ssh -c "test -f /home/vagrant/shell-test.txt && echo 'exists'" 2>&1
$result -join "`n" | Should -Match "exists"
}
}
}
# Separate Describe blocks for file, ansible, chef, salt...
Quick mode runs shell, file, and ansible (the working provisioners). Full mode adds chef and salt, which have known issues:
Describe "Vagrant WSL2 Provider - Chef Solo Provisioner" -Tag "KnownIssue" -Skip:(-not $Full) {
# Tests that we expect to fail due to chef symlink issues
}
Describe "Vagrant WSL2 Provider - SaltStack Provisioner" -Tag "KnownIssue" -Skip:(-not $Full) {
# Tests that we expect to fail due to bootstrap URL changes
}
The -Skip:(-not $Full) means these only run when you pass -Full. Chef and Salt are documented to fail, but the tests are there to track the issues.
Rakefile tasks:
rake test_provisioners # Test shell, file, and ansible
rake test_provisioners_full # Test all including chef and salt
Docker: 22 Distributions, Individual Machines
The Docker test validates that Docker installs and runs on different WSL distributions. The old examples/docker-test/Vagrantfile used a loop that auto-created all VMs:
# Old approach
DISTRIBUTIONS.each do |distro|
config.vm.define "docker-#{distro}" do |node|
# auto-created on vagrant up
end
end
This doesn’t work for selective testing. We refactored to individual machine definitions with autostart: false:
# New approach
config.vm.define "ubuntu2404", autostart: false do |node|
node.vm.box = "Ubuntu-24.04"
node.vm.provider "wsl2" do |wsl|
wsl.distribution_name = "vagrant-docker-ubuntu2404"
wsl.version = 2
wsl.systemd = true
end
node.vm.provision "ansible_local" do |ansible|
ansible.playbook = "provisioning/docker-debian.yml"
end
end
config.vm.define "debian", autostart: false do |node|
# ...
end
# ... 22 machines total
Now you can run vagrant up ubuntu2404 to test just one, or the Pester test can selectively spin up what it needs.
The test uses the same quick/full pattern:
# Docker.Tests.ps1
param([switch]$Full)
BeforeAll {
$script:QuickMachines = @(
@{ Name = "ubuntu2404"; Distro = "vagrant-docker-ubuntu2404" },
@{ Name = "debian"; Distro = "vagrant-docker-debian" },
@{ Name = "almalinux8"; Distro = "vagrant-docker-almalinux8" }
)
$script:AllMachines = @(
# All 22 distributions
)
$script:TestMachines = if ($Full) {
Write-Host "Running FULL Docker test (all $($script:AllMachines.Count) distributions)"
$script:AllMachines
} else {
Write-Host "Running QUICK Docker test ($($script:QuickMachines.Count) distributions)"
$script:QuickMachines
}
}
Describe "Vagrant WSL2 Provider - Docker Support" {
Context "When testing Docker installation across distributions" {
It "Should successfully bring up <Name> with Docker" -ForEach $script:TestMachines {
vagrant up $Name --provider=wsl2
$LASTEXITCODE | Should -Be 0
}
}
}
Rakefile tasks:
rake test_docker # 3 distros
rake test_docker_full # 22 distros
The Parameter Passing Bug
To pass the -Full parameter from Invoke-PesterTests.ps1 to the test scripts, we had broken code:
# This doesn't work - ContainerParameters doesn't exist in Pester 5.x
$config.Run.ContainerParameters = @{ Full = $true }
The fix uses New-PesterContainer:
# Invoke-PesterTests.ps1
if ($Full) {
$container = New-PesterContainer -Path $TestPath -Data @{ Full = $true }
$config.Run.Container = $container
} else {
$config.Run.Path = $TestPath
}
This is the correct way to pass parameters to Pester 5.x test scripts. Works for AllDistributions, Provisioners, and Docker tests.
What’s Still Broken
The Docker test isn’t discovering tests yet:
Discovery found 0 tests in 211ms.
The -ForEach $script:TestMachines parameter binding isn’t working. Something’s wrong with how we’re structuring the test data or the Describe block. That’s next session’s problem - we’re out of context.
What We Shipped
Provisioners.Tests.ps1 - Tests all 5 provisioners (shell, file, ansible, chef, salt)
Refactored provisioner examples - Individual Vagrantfiles for each provisioner
Docker.Tests.ps1 - Tests Docker across distributions
Refactored docker-test Vagrantfile - Individual machine definitions
Fixed parameter passing -
Invoke-PesterTests.ps1now usesNew-PesterContainerproperlyUpdated Rakefile - New test tasks
Updated CLAUDE.md - Documented the new tests and structure
The TODO tests are no longer TODO. They’re implemented - just need to fix the Docker test discovery issue.
Vagrant WSL2 Provider is an MIT-licensed open source project. Check it out on GitHub.
Top comments (0)