Skip to content

Switch to rust-vmm-ci #14

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

Merged
merged 7 commits into from
Mar 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ steps:
platform: x86_64.metal
plugins:
- docker#v3.0.1:
image: "rustvmm/dev:v2"
image: "rustvmm/dev:v5"
always-pull: true

- label: "build-musl-x86-bzimage"
Expand All @@ -22,5 +22,5 @@ steps:
platform: x86_64.metal
plugins:
- docker#v3.0.1:
image: "rustvmm/dev:v2"
image: "rustvmm/dev:v5"
always-pull: true
176 changes: 0 additions & 176 deletions .buildkite/rust-vmm-ci-pipeline.yml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore/.gitignore → .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target
**/*.rs.bk
Cargo.lock
.idea/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "rust-vmm-ci"]
path = rust-vmm-ci
url = https://github.com/rust-vmm/rust-vmm-ci.git
82 changes: 17 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,88 +18,40 @@ cargo build
Our Continuous Integration (CI) pipeline is implemented on top of
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, the readme should be updated as well now that we use the rust-vmm-ci directly. In other repositories we just linked the rust-vmm-ci and got rid of all the other details.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done ✔️

[Buildkite](https://buildkite.com/).
For the complete list of tests, check our
[CI pipeline](https://buildkite.com/rust-vmm/vm-virtio-ci).
[CI pipeline](https://buildkite.com/rust-vmm/rust-vmm-ci).

Each individual test runs in a container. To reproduce a test locally, you can
use the dev-container on both x86 and arm64.

```bash
container_version=5
docker run -it \
--security-opt seccomp=unconfined \
--volume $(pwd):/linux-loader \
rustvmm/dev:v2
rustvmm/dev:v${container_version}
cd linux-loader/
cargo test
```

### Test Profiles

The integration tests support two test profiles:
- **devel**: this is the recommended profile for running the integration tests
on a local development machine.
- **ci** (default option): this is the profile used when running the
integration tests as part of the the Continuous Integration (CI).

The test profiles are applicable to tests that run using pytest. Currently only
the [coverage test](tests/test_coverage.py) follows this model as all the other
integration tests are run using the
[Buildkite pipeline](https://buildkite.com/rust-vmm/vm-virtio-ci).

The difference between is declaring tests as passed or failed:
- with the **devel** profile the coverage test passes if the current coverage
is equal or higher than the upstream coverage value. In case the current
coverage is higher, the coverage file is updated to the new coverage value.
- with the **ci** profile the coverage test passes only if the current coverage
is equal to the upstream coverage value.

Further details about the coverage test can be found in the
[Adaptive Coverage](#adaptive-coverage) section.

### Adaptive Coverage
### bzImage test

The line coverage is saved in [tests/coverage](tests/coverage). To update the
coverage before submitting a PR, run the coverage test:
As we don't want to distribute an entire kernel bzImage, the `load_bzImage`
test is ignored by default. In order to test the bzImage support, one needs to
locally build a bzImage, copy it to the `src/loader` directory and run
`cargo test`:

```bash
# Assuming your linux-loader and linux-stable are both under ${LINUX_LOADER}:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git ${LINUX_LOADER}/linux-stable
cd linux-stable
make bzImage
cp linux-stable/arch/x86/boot/bzImage ${LINUX_LOADER}/linux-loader/src/loader/
cd ${LINUX_LOADER}/linux-loader
container_version=5
docker run -it \
--security-opt seccomp=unconfined \
--volume $(pwd):/linux-loader \
rustvmm/dev:v2
rustvmm/dev:v${container_version}
cd linux-loader/
pytest --profile=devel tests/test_coverage.py
```

If the PR coverage is higher than the upstream coverage, the coverage file
needs to be manually added to the commit before submitting the PR:

```bash
git add tests/coverage
```

Failing to do so will generate a fail on the CI pipeline when publishing the
PR.

**NOTE:** The coverage file is only updated in the `devel` test profile. In
the `ci` profile the coverage test will fail if the current coverage is higher
than the coverage reported in [tests/coverage](tests/coverage).

### bzImage test

As we don't want to distribute an entire kernel bzImage, the `load_bzImage` test is ignored by
default. In order to test the bzImage support, one needs to locally build a bzImage, copy it
to the `src/loader` directory and run cargo test:

```shell
# Assuming your linux-loader and linux-stable are both under $LINUX_LOADER
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git $LINUX_LOADER/linux-stable
$ cd linux-stable
$ make bzImage
$ cp linux-stable/arch/x86/boot/bzImage $LINUX_LOADER/linux-loader/src/loader/
$ cd $LINUX_LOADER/linux-loader
$ docker run -it \
--security-opt seccomp=unconfined \
--volume $(pwd):/linux-loader \
rustvmm/dev:v2
$ cd linux-loader/
$ cargo test
cargo test
```
5 changes: 5 additions & 0 deletions coverage_config_aarch64.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"coverage_score": 71,
"exclude_path": "",
"crate_features": ""
}
5 changes: 5 additions & 0 deletions coverage_config_x86_64.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"coverage_score": 75.9,
"exclude_path": "",
"crate_features": ""
}
1 change: 1 addition & 0 deletions rust-vmm-ci
Submodule rust-vmm-ci added at cd7096
2 changes: 1 addition & 1 deletion src/loader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ pub fn load_cmdline<M: GuestMemory>(
.checked_add(len as u64 + 1)
.ok_or(Error::CommandLineOverflow)?; // Extra for null termination.
if end > guest_mem.last_addr() {
return Err(Error::CommandLineOverflow)?;
return Err(Error::CommandLineOverflow);
}

guest_mem
Expand Down
14 changes: 10 additions & 4 deletions src/loader/struct_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ pub enum Error {
pub type Result<T> = std::result::Result<T, Error>;

/// Reads a struct from an input buffer.
/// This is unsafe because the struct is initialized to unverified data read from the input.
/// `read_struct` should only be called to fill plain old data structs. It is not endian safe.
///
/// # Arguments
///
/// * `f` - The input to read from. Often this is a file.
/// * `out` - The struct to fill with data read from `f`.
///
/// # Safety
///
/// This is unsafe because the struct is initialized to unverified data read from the input.
/// `read_struct` should only be called to fill plain data structs. It is not endian safe.
pub unsafe fn read_struct<T: Copy, F: Read>(f: &mut F, out: &mut T) -> Result<()> {
let out_slice = std::slice::from_raw_parts_mut(out as *mut T as *mut u8, mem::size_of::<T>());
f.read_exact(out_slice).map_err(|_| Error::ReadStruct)?;
Expand All @@ -33,13 +36,16 @@ pub unsafe fn read_struct<T: Copy, F: Read>(f: &mut F, out: &mut T) -> Result<()

/// Reads an array of structs from an input buffer. Returns a Vec of structs initialized with data
/// from the specified input.
/// This is unsafe because the structs are initialized to unverified data read from the input.
/// `read_struct_slice` should only be called for plain old data structs. It is not endian safe.
///
/// # Arguments
///
/// * `f` - The input to read from. Often this is a file.
/// * `len` - The number of structs to fill with data read from `f`.
///
/// # Safety
///
/// This is unsafe because the struct is initialized to unverified data read from the input.
/// `read_struct_slice` should only be called to fill plain data structs. It is not endian safe.
#[cfg(feature = "elf")]
pub unsafe fn read_struct_slice<T: Copy, F: Read>(f: &mut F, len: usize) -> Result<Vec<T>> {
let mut out: Vec<T> = Vec::with_capacity(len);
Expand Down
28 changes: 0 additions & 28 deletions tests/conftest.py

This file was deleted.

1 change: 0 additions & 1 deletion tests/coverage

This file was deleted.

Loading