Closed james-stocks closed 5 years ago
Hi @james-stocks
This repo has not yet adopted the new open source practices, so you have several options here:
Submit this as an RFC to the existing RFC repo process: https://github.com/habitat-sh/core-plans-rfcs
Wait until the maintainers have converted all of the existing RFCs to be in line with the new OSS design process and submit it then.
Proposal for CI
Recommendation: We should use
CI
in place ofBuildkite
, unless we specifically need to refer to the Buildkite service. This separates the idea of "We should run automated tests" from "we have chosen Buildkite to run the tests". Also, while I don't expect it to change anytime soon, we'd have to rewrite this if we were to change our CI service π* `tests/test.sh` and `tests/test.ps1` will build the package before running the tests.
I'm a pretty hard π on this. tests/test.sh should take an artifact as input and not concern itself with the build at all. This gives us the flexibility to use the same set of tests against artifacts from builder, allowing us to test the results of a build group, though as you note in the "downstream impacts" section this is a separate topic on if/how that gets wired up.
The scripts also shouldn't have the concept of maybe build. I'd want to verify on every CI run that the environment was set up correctly such that it didn't accidentally build the package because the interface in deciding how to build changed, or something in CI causes an inadvertent change in behavior.
* ./tests/test.sh script runs the build, install, and tests and must work on a Buildkite build agent. * There is an existing convention to set the environment variable `SKIPBUILD` to have the test script only run tests - new plans should implement this.
Same comments as above.
@james-stocks Also I want to assure you that I'm not giving you the run around on this topic. I know you and @gavindidrichsen are working hard on providing tests for core-plans.
It's best that we solve these problems individually and discuss these things in long form. Just to be clear, there are several things happening right now:
These discussions are somewhat dependent on each other, but I think it's safe to say that this is the order that we should solve them in, as it will help make each subsequent problem a little easier to solve.
Again, thank you for your patience as the community and maintainers work to solve these problems!
@echohack I don't think this needs be closed out or moved to an RFC while the migration from RFC to design proposal is in progress.
I agree that this should remain open until we've done the appropriate work for that migration though.
I encourage people to continue to comment on this issue in the mean time.
We should use CI in place of Buildkite
Updated the issue.
tests/test.sh should take an artifact as input and not concern itself with the build at all. This gives us the flexibility to use the same set of tests against artifacts from builder
I have a little uncertainty here because one of the main tests for plans is to query the software's version and compare it to what should be built e.g.
source "${BATS_TEST_DIRNAME}/../plan.sh"
@test "Version matches" {
result="$(rg --version | head -1 | awk '{print $2}')"
[ "$result" = "${pkg_version}" ]
}
If we design the tests to be re-used then we need some mechanism to get the expected version of the software that works both for building the plan from a git clone of this repo (i.e. the CI here) and when testing as a builder artifact. Maybe there is some directory and file under /hab/pkgs
that will present in any case, that the test can read?
Aside from that, it sounds like you are suggesting that:
Is that right, or were you thinking of something different?
This sounds good to me; but it differs from how plans for tests are written today and we'd need to handle existing plan tests failing in this new CI setup.
In my opinion, we shouldn't be sourcing the plan in the test. That blurs the line between testing the resulting artifact and testing that plan-build did what it said it would.
I also don't think testing the version provides value for the same reason, with the possible exception of builds that use version control that is not easily controlled by plan-build. Go based packages come to mind.
In these cases it may be fine to expect certain variables to be defined in the environment, such as ones that can be sourced from last_build.env
. That still feels a little off to me though. We don't provide a VERSION file in the metadata of a package, only IDENT
, so there's no easy win there without writing libraries π
My personal belief is that CI should drive the flow, and allow each discrete piece (in this case tests) to focus on their role in the process. If a user wants to run the tests locally, they should be able to run the CI script directly if the platform allows it.
I don't want dive into solutioneering in this, but to illustrate:
build <input> # plan-build always takes a plan directory as input.
source results/last_build.env # plan-build always provides us with this as an output, which we can use to get the $pkg_ident of the thing we just built.
<input>/test.sh $pkg_ident # Similar to plan-build, the input contract is always a single item, in this case a fully qualified ident.
No matter how this discussion goes, I think we'll have to grandfather existing tests until they have a PR opened against them and adjust according on a case-by-case basis to bring them in line with our final decision.
Why donβt we have the last_build.env
have the pkg_version
?
@bdangit
That seems like an easy thing to add... :)
Edit: Wait, it already has pkg_version
, soooo....
It's seems obvious to me that the version check could easily reference last_build.env
already!
My uncertainty about using last_build.env
relates to this comment from @smacfarlane :
This gives us the flexibility to use the same set of tests against artifacts from builder, allowing us to test the results of a build group
If the tests are being run against an artifact from builder, there will not be a last_build.env
file.
It looks like we can determine it from /hab/pkgs/core/[PACKAGE]/[VERSION]/[STAMP]/IDENT
?
If the tests are being run against an artifact from builder, there will not be a
last_build.env
file.
Yup, this is in part why I think the test should take a fully qualified package ident as a parameter and not source anything. CI will know what it just built and pass that identifier to the tests. Likewise builder will know the idents of the things that need to be tested (whatever shape that work ends up taking).
Test implementation
I'd like to propose an addition to this section,
Tests should not use hab pkg binlink
.
When executing commands that have been "binlinked", you lose environmental correctness that hab pkg exec
and the lifecycle hooks give you. I've put together a couple examples to demonstrate:
Simple
sed
wrapper that demonstrates how "binlinking" can mask missing dependencies: https://gist.github.com/smacfarlane/d92fef5b7f4030c0027c285e2310e2e5#file-sed-wrapperAn example of compiled software that has a different
PATH
depending on how it was executed, leading to potentially executing a version of software you didn't explicitly depend on: https://gist.github.com/smacfarlane/d92fef5b7f4030c0027c285e2310e2e5#file-coreutils-exampleAn example of interpreted software that relies on environmental variables being present in order to function:
https://gist.github.com/smacfarlane/d92fef5b7f4030c0027c285e2310e2e5#file-env-vars-example
Tests should not use
hab pkg binlink
I agree with this but would like to word it as:
Tests should use
hab pkg exec
and should not usehab pkg binlink
...because the examples you gave all demonstrate why to use hab pkg exec
but do not all use binlink
to demonstrate the pitfall.
I hope it is OK to copy your example gists directly into this design?
"Downstream Impact" should possibly be re-worded because it says these tests are not used on builder; but part of the discussion above is that we should write tests that could be re-used on builder
tests/test.sh
andtests/test.ps1
will build the package before running the tests.
This statement should change, I agree with @smacfarlane on
the test should take a fully qualified package ident as a parameter and not source anything. CI will know what it just built and pass that identifier to the tests. Likewise builder will know the idents of the things that need to be tested (whatever shape that work ends up taking).
I would suggest standardising on an env var that should be set for the tests e.g. PACKAGE_IDENT
.
I suggest an env var rather than passing the ident as a parameter on CLI because at least BATS does not support arguments - it will need to find the package ident either in the environment or in a file.
I suggest an env var rather than passing the ident as a parameter on CLI because at least BATS does not support arguments - it will need to find the package ident either in the environment or in a file.
I do think it should be a parameter, as that makes the input to the tests explicit when called. You would then have to set and export the expected env var in bats which does feel kinda silly.
I don't have a strong preference either way, as long as we're consistent. The above is why I recommended a parameter though.
Let's go with parameter. It looks like Pester accepts parameters at the command line so BATS would be the odd-one-out in this case.
I'm unsure about this bit:
- For the time being, the build should not fail if tests/test.sh or tests/test.ps1 does not exist.
This might cause confusion because a PR reviewer is going to have to dig into the CI build to see if tests executed and passed. It's unhelpful for a human to need to go and inspect a CI build that is green. The alternative is to fail the build if tests are missing - this will be an inconvenience to someone making a small contribution and having the burden of setting up tests put on them.
This problem will only be temporary as we aim to add tests to all plans.
Edit: by coincidence I just noticed @tduffield mention that BuildKite now supports a soft_fail and that might be an option in this case.
Is the first Comment updated with all comments here? I have not have time to review this as yet.
I believe I've worked all the comments into the original issue except for my own question in the last comment.
I guess I should :+1: any comment that's been resolved.
On Tue, 30 Apr 2019, 5:26 pm Graham Weldon, notifications@github.com wrote:
Is the first Comment updated with all comments here? I have not have time to review this as yet.
β You are receiving this because you were assigned. Reply to this email directly, view it on GitHub https://github.com/habitat-sh/core-plans/issues/2473#issuecomment-488020414, or mute the thread https://github.com/notifications/unsubscribe-auth/AC4TBWMCNOZDQWEAEQ2JMYTPTBXKJANCNFSM4HGT3OHQ .
The review period for this design has ended. As per the OSS design process, I've raised a PR to commit this to the project: https://github.com/habitat-sh/core-plans/pull/2539
(NOTE: this issue template and review process for this issue follow the updated Chef OSS practices Comments with a π reaction have been addressed (either in changes to this design or in subsequent comments) - readers wishing to catch up can ignore comments with a π reaction and review the current issue text + any remaining comments not marked π )
core-plans testing standard
Chef wants to ensure the highest level of quality and best developer experience for projects that choose to build their software with Habitat. Part of that goal is to set a standard for quality assurance in this repository.
Motivation
Specification
There are two aspects to this design:
Scope of Testing
It's essential to define and agree on the scope of testing. Testing must cover all aspects of quality that this repository is responsible for; and testing must also not exceed what the code in this repository does - if a failing test would not be fixed via a change to this repository, the test does not belong in this repository.
In-Scope for Testing
--help
at-once
.Out-of-Scope for Testing
Implementation of Automated Tests in core-plans
CI configuration
core-Plans currently has CI configuration to detect what plans have been modified and need tested (see here). If a core plan has a
tests
directory, the contents should be run during CI for a Pull Request.Proposal for CI
tests/test.sh
andtests/test.ps1
if either exists inside the directory of a plan that has been modified.tests/test.sh
ortests/test.ps1
will not require any pre-installed software other than what is available on the CI build agent.tests/test.sh
ortests/test.ps1
does not exist.tests/test.sh
ortests/test.ps1
exits with a non-zero exit code.tests/test.sh
ortests/test.ps1
, with the fully qualified package ident of the built package to test as a parameter.Test implementation
tests/test.sh
/tests/test.ps1
) should take the fully qualified package ident for a currently installed package as a parameter.hab pkg exec
to execute the binary.hab pkg binlink
should not be used. See the [Appendix] for some examples to demonstrate why.tests
folder structureStructure below is proposed as common format for the core plan testing directory with the following features:
SKIPBUILD
to have the test script only run tests - new plans should implement this.Downstream Impact
There should be no negative downstream impacts. Builder will continue to build new unstable packages when commits are merged in this repository. It is intended that tests implemented according to this design can be run against artifacts on builder (or other downstream environments); but how that will actually happen is future work.
Appendix
Examples of why
hab pkg exec
should be used