Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[test] Update WCOW uVM and vSMB, and HostProcess functional tests #1965

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

helsaawy
Copy link
Contributor

@helsaawy helsaawy commented Nov 9, 2023

Update and un-skip WCOW uVM and container tests as well as WCOW vSMB tests.

Add:

  • WCOW uVM benchmarks
  • LCOW boot file tests that verify kernel boot args and dmesg logs
  • WCOW Host Process tests, including dedicated tests for setting username, and verifying hostname and volume mounts.

Unified container and uVM lifecycle, exec, and IO tests for LCOW and WCOW.

Moved tests from:

  • lcow_bench_test.go to uvm_bench_test.go
  • lcow_container_test.go to container_test.go
  • lcow_test.go to lcow_uvm_test.go and uvm_test.go

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

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.

PR is split into two commits: the first does preparatory reorg work, specifically for LCOW-only tests that are generalized to work on both LCOW and WCOW in the subsequent commit.

@helsaawy helsaawy added the tests Pull requests that modify tests label Nov 9, 2023
@helsaawy helsaawy force-pushed the func-tests branch 2 times, most recently from 241c958 to f056672 Compare November 10, 2023 19:59
@helsaawy helsaawy changed the title Func tests [test] Update WCOW uVM and vSMB, and HostProcess functional tests Dec 7, 2023
@helsaawy helsaawy force-pushed the func-tests branch 4 times, most recently from 4c91058 to 2d896c5 Compare December 12, 2023 20:52
@helsaawy helsaawy marked this pull request as ready for review March 28, 2024 18:24
@helsaawy helsaawy requested a review from a team as a code owner March 28, 2024 18:24
@helsaawy helsaawy force-pushed the func-tests branch 2 times, most recently from f592f71 to fcb7cc9 Compare April 2, 2024 15:16
@ambarve
Copy link
Contributor

ambarve commented Apr 8, 2024

Seems like there are a bunch of changes combined in this PR, would it be possible to split it into multiple commits so that it is easier to review?

WCOW tests can be integrated directly into existing LCOW tests as
subtests, after generalizing the original (LCOW-only) tests to run both
types of uVMs and containers.

Break the change into two:
(1) move (and rename) the original LCOW-only tests; and
(2) generalize the tests and add the WCOW components.

To simplify the diffs, this commit only includes the first process.
Specifically, move:
 - `lcow_bench_test.go` to `uvm_bench_test.go`
 - `lcow_container_test.go` to `container_test.go`
 - `lcow_test.go` to `lcow_uvm_test.go`

Within `lcow_uvm_test.go`, combine and generalize kernel arg tests
(i.e., `TestLCOW_UVMNoSCSINoVPMemInitrd` and
`TestLCOW_UVMNoSCSISingleVPMemVHD`) to `TestLCOW_UVM_KernelArgs`.

Combine and generalize boot/time tests (e.g.,
`TestLCOW_TimeUVMStartVHD`, `TestLCOW_UVMStart_KernelDirect_VHD`) to
`TestLCOW_UVM_Boot`.

Also, since go1.21, `"github.com/Microsoft/hcsshim/internal/sync"` is no
longer necessary, so replace it with `"sync".OnceValue[s]`.

Signed-off-by: Hamza El-Saawy <hamzaelsaawy@microsoft.com>
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 <hamzaelsaawy@microsoft.com>

ioArgs.TestStdOutContains(t, tc.wantArgs, tc.notWantArgs)

// some boot options (notably using initrd) need to validated by looking at dmesg logs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If dmesg output has the entire command line (i.e. what we are reading from /proc/cmdlind plus some other options) why not only read dmesg logs and avoid reading /proc/cmdline?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basically cause the TestStdOutContains function checks that the sting contains each of args, so unless we first parse the dmesg output for only the command line bit, the check might turn a false positive if the arg we want shows up elsewhere in the logs.
I didn't want to assume a stable output for dmesg, nor a stable ordering of the arguments in the command line (eg, searching for the string root=/dev/sda rootwait init=/init instead of each component individually)

require.Build(t, osversion.RS5)
requireFeatures(t, featureLCOW, featureUVM)

numIters := 3
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of doing 3 iterations of this? If it is to catch any concurrency issues, should we do 3 starts in 3 parallel goroutines?

Copy link
Contributor Author

@helsaawy helsaawy May 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its in serial, and the original tests had it (

for i := 0; i < 3; i++ {
), so i just kept it

Comment on lines +90 to +101
var fileBindingSupportedOnce = sync.OnceValue(func() bool {
// TODO: use windows.NewLazySystemDLL("bindfltapi.dll").Load() (or windows.LoadLibraryEx directly)

root := os.Getenv("SystemRoot")
if root == "" {
root = `C:\windows` // shouldn't really need this fall back, but ...
}
bindDLL := filepath.Join(root, `system32\bindfltapi.dll`)
st, err := os.Stat(bindDLL)
return err == nil && st.Mode().IsRegular()
})

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just do this in an init function and set a FileBindingSupported variable?

Also, since this isn't a test code change, we should probably make it into a separate commit, in case we need to revert stuff.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can make a separate commit/PR, but my worry with exposing the variable directly is it can be (inadvertently) changed, which id like to prevent doing

if !errors.Is(errGive, err) {
tb.Fatalf("got stderr: %v; wanted: %v", errGive, err)
outGot, errGot := b.Output()
if !errors.Is(errGot, err) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If errGot is say errors.New("file not found") will it match with os.ErrNotExist?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, errors.Is checks that it matches the original error object, not the message itself

out = strings.ToLower(strings.TrimSpace(out))
outGot = strings.ToLower(strings.TrimSpace(outGot))
if diff := cmp.Diff(out, outGot); diff != "" {
tb.Fatalf("stdout mismatch (-want +got):\n%s", diff)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stdout could be huge, probably should avoid logging the entire diff. Same for the function below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i tried that, but i found that whenever the test failed, having the stdout in the logs was pretty helpful to debug the failure immediately.
otherwise i went down a rabbit hole of replicating locally and then logging stdout anyways

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tests Pull requests that modify tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants