Implement the Test Kitchen 4 driver APIs and modernize the driver - #164
Conversation
8c852c2 to
0d96d56
Compare
Audits the driver against test-kitchen 4.1.1 (the current release) and
closes the gaps. The dependency ceilings were already right; what was
missing was the driver's side of three APIs, plus two real bugs.
Test Kitchen APIs
- pre_create_command was silently ignored. Kitchen::Driver::Base#create
is not empty -- it runs config[:pre_create_command] -- and Hyperv#create
overrode it without calling super, so anyone setting the option got
nothing and no error. It now runs before any PowerShell.
- status(state) is implemented, backing `kitchen list --probe`. Test
Kitchen 4 added it with an explicit note that drivers able to ask their
provider should override it; this driver can. It is deliberately
read-only and uses a new Get-VmStatus helper rather than
Assert-VmRunning, so probing a stopped instance reports it as stopped
instead of booting it.
- doctor(state) is implemented, backing `kitchen doctor`. It reports a
missing Hyper-V module, an unreachable host, and a missing or
unreadable parent VHD, and returns every problem it finds rather than
stopping at the first.
Bugs
- `kitchen diagnose` raised TypeError: no implicit conversion of nil into
String. diagnose evaluates every lazy default, and the disk_type block
called File.extname on a nil parent_vhd_name.
- Windows on ARM hosts could not launch PowerShell at all. The width
checks matched only AMD64, so on ARM64 both were false and the driver
fell through to the Sysnative path, which does not exist for a native
64-bit process. Architecture detection now recognizes ARM64 and IA64,
and reads Ruby's pointer width from RbConfig::SIZEOF rather than
["foo"].pack("p").size. Sysnative is reached only in the genuine WOW64
case it was written for.
PowerShell
Set-VMNetworkConfiguration is ported from Get-WmiObject and the [WMI]
type accelerator, both removed in PowerShell 6, to Get-CimInstance and
Invoke-CimMethod. Behaviour on Windows PowerShell 5.1 is unchanged; the
static IP path is no longer what would block running under pwsh. The
NetworkConfiguration parameter is declared string[] of embedded
instances, which the CIM layer serializes from the CimInstance, replacing
GetText(1). A failed configuration job now raises instead of emitting the
error and carrying on, which previously hid a failed address assignment
behind a successful create. Also fixes a latent typo: the trailing lookup
read .NetworkAdapter, which is always nil, rather than .NetworkAdapters.
Modernization
- copy_vm_files and dry_run are declared via default_config. Both are
documented in the README but were invisible to `kitchen diagnose`.
- Dropped the unused mixlib/shellout requires from both lib files;
run_command comes from Kitchen::ShellOut via Driver::Base.
- Added frozen_string_literal magic comments.
- Renamed is_64bit?/is_32bit? to sixty_four_bit?/thirty_two_bit?, keeping
the old names as deprecated aliases since this is a published mixin.
- Raised the test-kitchen floor to >= 3.0. The previous >= 1.4 predates
pre_create_command, where the new super call would be a no-op.
Testing
120 RSpec examples and 45 Pester tests, all green. New coverage for
status, doctor, pre_create_command ordering, the diagnose crash, ARM64
and genuine-32-bit path selection, Get-VmStatus, and the CIM port.
Mutation-tested: dropping super, hardcoding status to running, reverting
ARM64, and swallowing the CIM job failure each fail their tests.
The CIM port cannot be verified here -- Pester proves the call shape, not
that Hyper-V accepts it -- so it wants a manual smoke test with
ip_address set against a real host before release.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
0d96d56 to
124e872
Compare
CI fix
Cause: rebasing this branch onto
Verified locally with the exact commands CI runs: On the size of the
|
What this does
Audits the driver against test-kitchen 4.1.1 — the current release — and closes the gaps.
The dependency ceilings were already correct (
< 5for test-kitchen, train 3.16.5 and train-winrm 0.4.3 are both current). What was missing was the driver's side of three Test Kitchen APIs, plus two real bugs.Test Kitchen APIs
pre_create_commandwas silently ignoredKitchen::Driver::Base#createis not empty — it runsconfig[:pre_create_command]:Hyperv#createoverrode it and never calledsuper, so anyone setting the option inkitchen.ymlgot silence, not an error. It now runs before any PowerShell reaches the host.status(state)— backskitchen list --probeTest Kitchen 4 added this with an explicit note: "Drivers that can ask their provider should override this method." This driver can. Today it reports
Kitchen::Driver::Hyperv does not support status checks.It is deliberately read-only. Reusing the existing
Assert-VmRunningwould have been less code, but that helper starts a stopped VM — so probing would have had the side effect of booting instances. A newGet-VmStatushelper reads power state without changing it, and reports a stopped instance as stopped.doctor(state)— backskitchen doctorReports a missing Hyper-V module, an unreachable host, and a missing or unreadable parent VHD. Returns every problem it finds rather than stopping at the first, since they're usually related.
Bugs
kitchen diagnosecrasheddiagnoseevaluates every lazy default, and thedisk_typeblock calledFile.extnameon a nilparent_vhd_name→TypeError: no implicit conversion of nil into String. Reproduced before fixing.AMD64. OnARM64bothis_64bit?andis_32bit?were false, sopowershell_64_bitfell through to the Sysnative path — which does not exist for a native 64-bit process. Everyrun_pscall failed.Architecture detection now recognizes
ARM64andIA64, and reads Ruby's pointer width fromRbConfig::SIZEOFrather than["foo"].pack("p").size. Sysnative is reached only in the genuine WOW64 case it was written for — a 32-bit Ruby on 64-bit Windows — which now has its own test.PowerShell: WMI → CIM
Set-VMNetworkConfigurationusedGet-WmiObjectand the[WMI]type accelerator, both removed in PowerShell 6. Behaviour on Windows PowerShell 5.1 is unchanged, but the static-IP path is no longer the thing that would hard-block running underpwsh.Get-WmiObject→Get-CimInstance.GetRelated(...)→Get-CimAssociatedInstance -ResultClassName$Service.SetGuestNetworkAdapterConfiguration($vm, $cfg.GetText(1))→Invoke-CimMethodOn that last one: the documented MOF signature declares
NetworkConfigurationasstring[]of embedded instances, which the CIM layer serializes from theCimInstance— that's what replacesGetText(1).Two behaviour changes worth calling out:
$job.GetError(), which emits the error and carries on — hiding a failed address assignment behind an apparently successfulcreate..NetworkAdapter(singular), which is always$null, rather than.NetworkAdapters. Harmless today because the driver discards that return value.Modernization
copy_vm_filesanddry_runare now declared viadefault_config. Both are documented in the README but were invisible tokitchen diagnose.require "mixlib/shellout"from both lib files —run_commandcomes fromKitchen::ShellOutviaDriver::Base.frozen_string_literalmagic comments.is_64bit?/is_32bit?→sixty_four_bit?/thirty_two_bit?, keeping the old names as@deprecatedaliases — this is a published mixin, so public methods don't just disappear.>= 3.0. The previous>= 1.4predatespre_create_command, where the newsupercall would be a silent no-op.Verification
Mutation-tested, so the new tests demonstrably can fail:
superfromcreatestatustorunningNotes for review
ip_addressset against a real host before release. Everything else is exercised by the suites.>= 3.0is the only user-visible dependency change. Test Kitchen 2 is EOL and Ruby >= 3.1 was already required, so this should affect nobody in practice.hyperv_insecurestill defaults totrue. Flipping it would break every remote user relying on WinRM's self-signed certificate, so per discussion it keeps its default and gains a README note explaining exactly what it disables and when to turn it off.kitchen list --probe,kitchen doctor,kitchen diagnose --all) in the README, including that probing is read-only.🤖 Generated with Claude Code