Skip to content

Commit

Permalink
Add WCOW and vSMB functional tests
Browse files Browse the repository at this point in the history
Un-skip and fix WCOW uVM and container tests.
Add WCOW:
- uVM benchmarks
- vSMB tests
- Host Process tests

For WCOW host process tests, add dedicated tests for setting
username, and verifying hostname and volume mounts.

Fix bug where removing a direct-mapped vSMB share fails.

Run (non-virtualization/uVM) functional tests within CI.

Starting Host Process containers requires SYSTEM to create a
process with a specified token, so use PsExec.exe (from sysutils)
to run tests.

Make sure container specs are created with the default working
directory (`C:\`), similar to how `internal\cmd` works).

Signed-off-by: Hamza El-Saawy <[email protected]>
  • Loading branch information
helsaawy committed May 28, 2024
1 parent cf31281 commit 06c744f
Show file tree
Hide file tree
Showing 13 changed files with 1,908 additions and 425 deletions.
59 changes: 56 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,30 @@ jobs:
- name: Install gotestsum
run: go install gotest.tools/gotestsum@${{ env.GOTESTSUM_VERSION }}

# Download PsExec so we can run (functional) tests as 'NT Authority\System'.
# Needed for hostprocess tests, as well ensuring backup and restore privileges for
# unpacking WCOW images.
- name: Install PsExec.exe
run: |
New-Item -ItemType Directory -Force '${{ github.workspace }}\bin' > $null
'${{ github.workspace }}\bin' | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
curl.exe -L --no-progress-meter --fail-with-body -o 'C:\PSTools.zip' `
'https://download.sysinternals.com/files/PSTools.zip' 2>&1
if ( $LASTEXITCODE ) {
Write-Output '::error::Could not download PSTools.zip'
exit $LASTEXITCODE
}
tar.exe xf 'C:\PSTools.zip' -C '${{ github.workspace }}\bin' 'PsExec*' 2>&1
if ( $LASTEXITCODE ) {
Write-Output '::error::Could not extract PsExec.exe'
exit $LASTEXITCODE
}
# accept the eula
& '${{ github.workspace }}/bin/psexec' -accepteula -nobanner cmd /c "exit 0" 2>$null
# run tests
- name: Test repo
run: ${{ env.GOTESTSUM_CMD }} -gcflags=all=-d=checkptr -tags admin -timeout=20m ./...
Expand Down Expand Up @@ -354,13 +378,42 @@ jobs:
${{ env.GOTESTSUM_CMD_RAW }} ./containerd-shim-runhcs-v1.test.exe '-test.v'
working-directory: test

- name: Build and run functional testing binary
run: |
${{ env.GO_BUILD_TEST_CMD }} ./functional
if ( $LASTEXITCODE ) {
Write-Output '::error::Could not build functional.test.exe'
exit $LASTEXITCODE
}
# PsExec doesn't load GOBIN into path, so resolve gotestsum path
$gotestsum = Get-Command -Name 'gotestsum' -CommandType Application -ErrorAction 'Stop' |
Select-Object -First 1 -ExpandProperty Source
if ( [string]::IsNullOrEmpty($gotestsum) ) {
Write-Output '::error::could not find 'gotestsum.exe' path'
exit $LASTEXITCODE
}
# Don't run uVM (ie, nested virt) or LCOW integrity tests
$cmd = '${{ env.GOTESTSUM_CMD_RAW }} ./functional.test.exe -exclude=LCOW,LCOWIntegrity,uVM -test.timeout=1h -test.v -log-level=info'
$cmd = $cmd -replace 'gotestsum', $gotestsum
Write-Host "gotestsum command: $cmd"
# Apparently, in a GH runner, PsExec always runs noninteractively (even with `-i`)
# and doesn't capture or redirect std IO.
# So redirect stdout/stderr to a file.
psexec -nobanner -w (Get-Location) -s cmd /c "$cmd > out.txt 2>&1"
$ec = $LASTEXITCODE
Get-Content out.txt
exit $ec
working-directory: test

# build testing binaries
- name: Build cri-containerd Testing Binary
run: ${{ env.GO_BUILD_TEST_CMD }} ./cri-containerd
working-directory: test
- name: Build functional Testing Binary
run: ${{ env.GO_BUILD_TEST_CMD }} ./functional
working-directory: test
- name: Build runhcs Testing Binary
run: ${{ env.GO_BUILD_TEST_CMD }} ./runhcs
working-directory: test
Expand Down
25 changes: 24 additions & 1 deletion internal/uvm/vsmb.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,12 @@ func forceNoDirectMap(path string) (bool, error) {
var info winapi.FILE_ID_INFO
// We check for any error, rather than just ERROR_INVALID_PARAMETER. It seems better to also
// fall back if e.g. some other backing filesystem is used which returns a different error.
if err := windows.GetFileInformationByHandleEx(h, winapi.FileIdInfo, (*byte)(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info))); err != nil {
if err := windows.GetFileInformationByHandleEx(
h,
winapi.FileIdInfo,
(*byte)(unsafe.Pointer(&info)),
uint32(unsafe.Sizeof(info)),
); err != nil {
return true, nil
}
return false, nil
Expand Down Expand Up @@ -282,6 +287,24 @@ func (uvm *UtilityVM) removeVSMB(ctx context.Context, hostPath string, readOnly,
return nil
}

// Cannot remove a directmapped vSMB share without first closing all open handles to the
// share files from inside the the uVM (otherwise, the removal would un-map the files from
// the uVM's memory and subsequent access's would fail).
// Rather than forgetting about the share on the host side, keep it (with refCount == 0)
// in case that directory is re-added back for some reason.
//
// Note: HCS (vmcompute.exe) issues a remove vSMB request to the guest GCS iff:
// - vmwp.exe direct mapped the vSMB share; and
// - the GCS (on its internal bridge) has the PurgeVSmbCachedHandlesSupported capability.
// We do not (currently) have the ability to check for either.
if !share.options.NoDirectmap {
log.G(ctx).WithFields(logrus.Fields{
"name": share.name,
"path": hostPath,
}).Debug("skipping remove of directmapped vSMB share")
return nil
}

modification := &hcsschema.ModifySettingRequest{
RequestType: guestrequest.RequestTypeRemove,
Settings: hcsschema.VirtualSmbShare{Name: share.name},
Expand Down
Loading

0 comments on commit 06c744f

Please sign in to comment.