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

Improved testing, property testing, device tests #75

Merged
merged 2 commits into from
Jun 10, 2021

Conversation

tsturzl
Copy link
Collaborator

@tsturzl tsturzl commented Jun 7, 2021

The first part of this PR addresses part of #8 by adding tests to the cgroup device v1 controller. This PR continues on to improve testing by adding traits to for generating inputs for property testing to a few oci-spec types, and subsequently using the traits to implement property testing for the following cgroup v1 controllers:

  • Devices
  • Hugetbl
  • Memory

A few more subsystems could benefit from this type of testing, but I don't believe it's worth the effort to implement it for every controller. The oci-spec traits are only available with a certain feature flag proptesting, to prevent the quickcheck dependency and the trait implementations from being included in regular builds.

Property testing should give us a much better chance of catching edge cases. It creates fewer tests which test a multitude of generated inputs, meaning we need fewer tests to catch the same issues. It also arguably provides many of the benefits of fuzzing, which ultimately aligns with the objectives of runtime safety. I feel like this is an excellent choice for areas with more complicated logic, not just writing values to files for example.

Let me know what you think, and if it's agreed that this is a good approach moving forward I will create another issue listing other areas where we could benefit from property testing.

property testing on devices

property testing hugetbl and memory controllers

fix comount checks
@tsturzl tsturzl requested review from utam0k and Furisto June 7, 2021 18:31
@tsturzl
Copy link
Collaborator Author

tsturzl commented Jun 7, 2021

I'm asking for 2 reviewers @utam0k and @Furisto to get input on testing moving forward. I think both your input is valuable here in determining whether or not this is a good approach, and generally getting a discussion going with both of you on testing moving forward.

@utam0k
Copy link
Member

utam0k commented Jun 7, 2021

This PR is superb. The changes in this PR are a bit big, so I don't think I'll be able to review it right away, so I'll try to find time to review it thoroughly.
I'd also like to have @Furisto review it as well.

denied_content == device.to_string()
}
})
.fold(true, |a, b| a && b)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
.fold(true, |a, b| a && b)
.all(|is_ok| is_ok)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good catch, I was actually looking for this exactly. Much cleaner and more idiomatic.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this change has been made in the recent commit

@@ -214,11 +214,11 @@ impl Memory {
let current_limit = Self::get_memory_limit(cgroup_root)?;
match resource.swap {
Some(swap) => {
let is_updated = swap == -1 || current_limit < swap;
let is_updated = swap <= -1 || current_limit < swap;
Copy link
Member

Choose a reason for hiding this comment

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

I think this change is a good thing. But have there actually been any such a case?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think it matches the test case better, but either way the tests pass. I think it might actually be useful here to see what the subsystem thinks of negative values. I'm not sure if the kernel will give a validation error for negative values less than -1 or if all negative values are considered unlimited. If it's the case that all negative values are unlimited then I would say this changed behavior is most correct, otherwise I'd say any negative value less than -1 should cause it's own expected failure and the tests should account for that. I'll look into this deeper, and leave a comment in the code to explain.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I decided to revert this. So if you set any of these below -1 it will result in an "Invalid Arguments" error, which will be the same thing that happens in Rust. We don't currently deal with any of the validation error's the kernel spits out, so I decided to just leave it. Eventually it might be nice to handle the error in the controller code and create our own set of errors to more reasonably represent what the error actually means, and provide some feedback of what the valid values actually are.

Comment on lines 120 to 121
let allowed_content =
std::fs::read_to_string(tmp.join("devices.allow")).expect("read to string");
Copy link
Member

Choose a reason for hiding this comment

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

I felt it easier to read the read_to_string import in the test scope.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I started thinking the same thing. At first it was only used a few times, but now it's getting pretty verbose.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am now importing read_to_string in to all of the tests I had touched with this PR.

Copy link
Member

@utam0k utam0k left a comment

Choose a reason for hiding this comment

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

@tsturzl
I added some comments. However, the whole direction is very cool.

@tsturzl
Copy link
Collaborator Author

tsturzl commented Jun 8, 2021

@utam0k Excellent feedback! I'll take a further look into this hopefully tomorrow.

@Furisto
Copy link
Collaborator

Furisto commented Jun 8, 2021

@tsturzl @utam0k
Thank you for this. I think its an interesting and cool approach. My concern is that it seems to encourage big complicated tests, which check for everything instead of small focused ones. I do not have practical experience with property based testing though and maybe this concern is unfounded. I can certainly see the appeal and am open to trying it out.

@tsturzl
Copy link
Collaborator Author

tsturzl commented Jun 8, 2021

@Furisto I don't think we'll want to stop writing smaller focused unit tests, and property testing isn't really useful everywhere. Especially in the case of some of these cgroup v1 controllers which are basically writing values to files. My concern comes when we start testing things like the Memory, Hugetbl, Blkio controllers which have more complicated behavior. I think we still keep the same method of testing, but simply add property testing where necessary. If it becomes a burden to keep up with or the test cases fail to provide utility it should be separated enough to easily pull out. I don't think currently we have broad enough tests cases, and writing out a bunch of static test data to cover every case would probably exceed the efforts of property testing to provide a far lesser depth of inputs. So admittedly this appeals to my laziness. In many cases having explicit testing for specific behavior is superior, but I say we still write those tests. So I see this more as a supplement to current means of testing rather than a replacement for it, this is why I still wrote some basic tests for the Devices Controller and left the previously written tests in place.

Copy link
Member

@utam0k utam0k left a comment

Choose a reason for hiding this comment

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

nice improvements!

@utam0k utam0k merged commit 32743ec into youki-dev:main Jun 10, 2021
ferrell-code added a commit to ferrell-code/youki that referenced this pull request Jul 18, 2021
add default handling when there isn't cgroup path in config.json.

organize the logger.

Merge pull request youki-dev#47 from utam0k/organize-log

organize the logger.
Merge pull request youki-dev#45 from utam0k/no-cgroup-path

add default handling when there isn't cgroup path in config.json.
ignore submodule artifacts.

add a comment in oci_spec.

make sure that config.json can be read regardless of where it is executed.

add the tutorial on using youki.

Merge pull request youki-dev#49 from utam0k/tutorial

add the tutorial on using youki.
update README.

Merge pull request youki-dev#50 from utam0k/edit-readme

update README.
Reorganize cgroup modules

cpu and mems is optional according to spec

Spike cgroupv2 implementation

Move CgroupManager to common module

Implement cgroup manager trait

Detect group version and create manager

Improve file write options

Implement string trait for controller types

style

Support cpu controller

Add test module

Style

Enable controllers along the hierarchy

Add tests for cpu controller

Add modules for controllers

Add tests for cpuset controller

Use Result consistently

Rework cgroup fs detection

Support removal of cgroup

Remove types module

Formatting only

Prefer v1 over v2

Fix integration test failure

Control selection of cgroup fs with env variable

Get rid of warnings

Merge pull request youki-dev#48 from Furisto/cgroupv2

Initial support for cgroups v2
cargo clippy.

make log level debug to get more information when ci failed.

Merge pull request youki-dev#53 from utam0k/fix-unstable-ci

make log level debug to get more information when ci failed. 4b260b0
Merge branch 'main' of github.com:utam0k/youki into HEAD

Merge pull request youki-dev#52 from utam0k/cargo-clippy

cargo clippy.
Align cgroup controller implementations

- Use common method to write to cgroup file
- Ensure that pid is always written to the cgroup

Merge pull request youki-dev#54 from Furisto/cg-common

Align cgroup controller implementations
add spec cli command

resolve conflicts

impl defaults for lots of structs

Consolidate cgroup test methods

Merge pull request youki-dev#57 from Furisto/cg-tests

Consolidate cgroup test methods
Update README.md

- Change comment out sign `//` to `#` in shell script
- Add new line at end of file

formatting

add back default attributes

Update comment

Merge branch 'main' of github.com:utam0k/youki into main

Update comment

Merge branch 'main' of github.com:YJDoc2/youki into main

Add 'Community' section to README.md

Merge pull request youki-dev#59 from nimrodshn/add_community_section_to_readme

Add 'Community' section to README.md
Update README: Split code section in tutorial

- Split code section in tutorial.

Merge pull request youki-dev#58 from aoki/main

Update README.md
Update comment, fix cargo-clippy warning

Merge pull request youki-dev#43 from YJDoc2/main

Add comments to create.rs
utam0k -> containers

Signed-off-by: Sora Morimoto <sora@morimoto.io>

Merge pull request youki-dev#61 from smorimoto/utam0k-containers

utam0k -> containers
Add cgroup v1 cpu controller

Add cgroup v1 cpuset controller

Unit tests for cgroup v1 cpu controller

Unit tests for cgroup v1 cpuset controller

Cut down on boilerplate

Activate cpu integration test

Fix error while moving task into cgroup

If a task is moved into the cgroup and a value has not been set for
cpus and mems Errno 28 (no space left on device) will be returned.
Therefore we set the value from the parent if required.

Improve reliability of cgroup removal

Merge pull request youki-dev#63 from Furisto/cg-cpu-v1

Support for cgroup v1 cpu and cpuset subsystem
Add comments to process module and minor refactoring

Changed hard coded mentions of poll time and event numbers to references of constants

Merge pull request youki-dev#64 from YJDoc2/main

Add comments to process module and minor refactoring
Added install command for prerequisite in README

Merge pull request youki-dev#66 from PeterYordanov/add-install-prerequisite

Added install command for prerequisite in README
Fixed spelling mistake in src/rootfs.rs

Merge pull request youki-dev#67 from PeterYordanov/spelling-mistake-rootfs

Fixed spelling mistake in src/rootfs.rs
add handling of WouldBlock error.

Use init pid instead of child pid

Ensure controllers are enabled at the root

Logging

Added folder structure section in README

Added folder structure section in README

Added resources to folder structure section

Fixed spelling mistakes

Added documentation comment for cgroup module

Added doc comments for modules

Removed folder structure section

Update doc comment

Merge pull request youki-dev#68 from utam0k/handle_wouldblock

add handling of WouldBlock error.
Create a template for integration tests.

refactore

Run fmt

Merge branch 'main' into add-spec-arg

Added doc on how to run integration tests

Update youki path

Change build command

Merge pull request youki-dev#73 from minakawa-daiki/fix-youki-path

Change execution path and fix CI
Merge branch 'main' into add-integration-template

Merge pull request youki-dev#69 from Furisto/cg-escape

Fix issues with cgroup v1 and v2
Merge pull request youki-dev#71 from minakawa-daiki/add-integration-template

Added Integration test template
basic device tests

property testing on devices

property testing hugetbl and memory controllers

fix comount checks

Updated doc comments

migrate LinuxCapabilityType to enum

Update caps_migrations.rs
Fixed typo

Unfinished sentence

Merge pull request youki-dev#70 from PeterYordanov/added-doc-comments-modules

Added doc comments modules
Add comments to container module

make LinuxCapabilityType

add some widgets to README.md

Merge pull request youki-dev#76 from utam0k/widget

add some widgets to README.md
Handle relative cgroup paths

Ensure parents have value

Merge pull request youki-dev#74 from Furisto/cg-relative

Handle relative cgroup paths
address requested changes

Merge pull request youki-dev#75 from tsturzl/main

Improved testing, property testing, device tests
impl From for Capabilities and add tests

Add comments to command module

Add draft-doc for container and command module

Merge branch 'main' of github.com:containers/youki into main

Merge pull request youki-dev#79 from YJDoc2/main

Document Container and Command modules
Fix README badges

fix github ci badge

typo...

Merge pull request youki-dev#80 from tsturzl/main

Fix badges in README
add create kill delete state in integration test

Merge pull request youki-dev#81 from duduainankai/add-integration-test

add create kill delete state in integration test
Provide better error messages

Merge pull request youki-dev#84 from Furisto/cg-better-errors

Provide better error messages
limit scope of unsafe

get rid of unneeded unsafes

make sure any values with `=` are not affected

Merge pull request youki-dev#85 from tsturzl/main

Clean up use of unsafe
Add info command

Merge pull request youki-dev#83 from Furisto/info-cmd

Add info command
Merge remote-tracking branch 'upstream/main' into add-spec-arg

resolve conflict

add lots of comments

Add CODE-OF-CONDUCT.md and SECURITY.md

Fix README link typo

Merge pull request youki-dev#88 from sasurau4/fix/readme-link

Fix README link typo
Merge pull request youki-dev#86 from utam0k/coc-security

Add CODE-OF-CONDUCT.md and SECURITY.md
docs

clean up around the tty.

Renamed Cond to Pipe

Merge pull request youki-dev#89 from utam0k/tty-refactor

clean up around the tty.
Merge pull request youki-dev#90 from YJDoc2/main

Rename Cond to Pipe
make sure to log any unimplemented controllers.

Merge pull request youki-dev#91 from utam0k/unknown-controller

make sure to log any unimplemented controllers.
Add support for cpuacct in cgroup v1.

Remove unnecessary processing.

use bail! insted of anyhow

Merge pull request youki-dev#92 from yjuba/v1-cpuacct

[WIP] Add support for cpuacct in cgroup v1.
Merge pull request youki-dev#94 from utam0k/bail

use bail! insted of anyhow
Add cgroup v1 freezer controller

Add a test for applying CpuAcct.

Merge pull request youki-dev#96 from yjuba/add-cpuacct-test

Add a test for applying CpuAcct.
improve build time in CI

Check if rootless container is required and ensure prerequisites

Ensure map binaries are available

Implement protocol for identifier mapping

Ensure root directory can be written by non root user

Identifier mapping names were not correct

Only one mapping needs to match

Prevent panic when resources are not specified

Fix wrong mapping

Clippy and fmt

Merge pull request youki-dev#93 from duduainankai/add-freezer

Add cgroup v1 freezer controller
remove the cargo-when dependency.

Address review comments

- should_use_rootless doesn't need Result type
- add warning regarding current rootless limitations
- make lookup_map_binary more concise

Merge pull request youki-dev#98 from Furisto/rootless

Experimental support for rootless containers
Add unit tests for tty module

Reuse tmpdir implementation from cgroup

Extend info cmd with version and os

Merge pull request youki-dev#102 from constreference/tty

Add unit tests for tty module
Merge pull request youki-dev#101 from Furisto/info-ex

Extend info cmd with version and os
Use `assert!` instead of `assert_eq!` when comparing a boolean.

Merge pull request youki-dev#104 from utam0k/fix-clippy

Use `assert!` instead of `assert_eq!` when comparing a boolean.
Add support for systemd managed cgroups

Merge pull request youki-dev#46 from nimrodshn/add_support_for_systemd_cgroups

Add support for systemd managed cgroups
update README.md

Merge pull request youki-dev#105 from utam0k/update-README

update README.md
clean up comments

Fix README.md Fedora & Centos instructions

Merge pull request youki-dev#107 from nimrodshn/fix_readme

Fix README.md Fedora & Centos instructions
Add list command

Merge pull request youki-dev#108 from Furisto/list-cmd

Add list command
fix conflicts.

Merge pull request youki-dev#97 from utam0k/actions-cache

improve build time in CI
split the subcommands into their own files.

Merge pull request youki-dev#110 from utam0k/refactor-cli-commands

split the subcommands into their own files.
Seperate adding tasks and applying resource restrictions

Shorten names

Update README.md

Change `dnf` to `apt-get` for Debian based systems
Address review comments
- Add comments for functions
- Use better naming in systemd cgroup manager

Merge pull request youki-dev#112 from bkochendorfer/patch-1

Update README.md
Merge pull request youki-dev#111 from Furisto/cg-add

Seperate adding tasks to cgroups and applying resource restrictions
Require only cgroups that are needed to fullfill the resource restrictions

Merge pull request youki-dev#114 from Furisto/cg-only-required

Require only requested cgroups to be present
force delete container if it is running or created

Merge pull request youki-dev#115 from TinySong/main

force delete container if it is running or created
add comments in intergration_test.sh about test case that runc no paas

Merge pull request youki-dev#116 from TinySong/main

add comments in intergration_test.sh about test case that runc no paas
remove unnecessary clone() in create.rs

Merge pull request youki-dev#117 from utam0k/refactor-create-remove-unnecessary-clone

remove unnecessary clone() in create.rs
Allow wider range of arguments for spec loading

Rename command

Provide context in case of errors during dir creation

Ensure file info is captured

Modularize create code

add cgroup v2 pid controller

Merge pull request youki-dev#119 from TinySong/main

add cgroup v2 pids controller
make String to signal conversion more user friendly by using a Trait.

add tests for the signal.

Split container builder into dedicated init and tenant builders

The current monolithic builder provides options that should only be called
during init and not when creating a tenant and vice versa. This puts the
burden on the user of the builder to know which methods are safe to call.
Now the ContainerBuilder can be used to specify options that are common to
both scenarios and afterwards as_init/as_tenant can be called to provide
scenario specific options. This also simplifies the whole "if init then else"
branching logic during container build.

Add documentation

Remove tests

Renaming

Fix kill cmd test failures

Execute doc tests

Merge pull request youki-dev#122 from utam0k/refactor-signal

make String to signal conversion more simplify by using a Trait.
Review feedback and fmt

Reduce binary size

Merge pull request youki-dev#124 from Furisto/release

Reduce size of binary
Add cgroup v2 freezer controller

Merge pull request youki-dev#123 from duduainankai/add-freezer-v2

Add cgroup v2 freezer controller
Merge pull request youki-dev#121 from Furisto/builder

Modularize container creation
fix the warnings shown by cargo clippy

support cgroupv2 io controller

Merge pull request youki-dev#128 from TinySong/cgroupv2-io-controller

Cgroupv2 io controller
Merge pull request youki-dev#127 from utam0k/cargo-clippy-2

fix the warnings shown by cargo clippy
Add code format check in CI

format code to pass CI check

Merge pull request youki-dev#129 from duduainankai/add-format-check-ci

Add format check ci
Fix spec path in delete

Merge pull request youki-dev#130 from duduainankai/fix-path-in-delete

Fix spec path in delete
Document Capabilities and refactor its drop_privileges function

Merge branch 'main' of github.com:containers/youki into comment-capabilities

Fix same tmp dir in freezer v2 tests

Merge pull request youki-dev#133 from duduainankai/fix-tmp-dir-in-test

Fix same tmp dir in freezer v2 tests
Merge pull request youki-dev#131 from YJDoc2/comment-capabilities

Document capabilities rs and refactor its drop_privileges function
cgroupsv2 hugetlb

remove regex usage from hugetlb v2

use different temp dir for hugetlbv2 tests

Document Info module

Update doc-draft.md

Merge pull request youki-dev#136 from YJDoc2/main

Document Info module
Document list module

Merge pull request youki-dev#135 from 0xdco/cgroups-v2-hugetlb

cgroupsv2 hugetlb
Comment and modify Log module:
Now the default log level is set according to type of compilation debug/production

Merge branch 'main' of github.com:containers/youki into main

Merge pull request youki-dev#137 from YJDoc2/main

Document list and logger modules
Implement exec command

Support calling exec multiple times

Fix test failure

Remove todo

Add comments

Merge pull request youki-dev#138 from Furisto/exec

Implement exec command
Add pause and resume command

conflicts

Merge branch 'main' into add-spec-arg
final issue

split into multiple files

add serde defaults to fields

Merge pull request youki-dev#139 from duduainankai/support-pause-resume

Add pause and resume command
Merge branch 'main' into add-spec-arg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants