-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
run integration tests with various git versions #2459
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
Conversation
Uffizzi Ephemeral Environment
|
ccb4444
to
b2dfb7b
Compare
@@ -22,7 +22,8 @@ var PullRebase = NewIntegrationTest(NewIntegrationTestArgs{ | |||
shell.SetBranchUpstream("master", "origin/master") | |||
|
|||
shell.HardReset("HEAD^^") | |||
shell.EmptyCommit("four") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in older Git (2.??), git pull --rebase
doesn't keep empty commits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This begs the question of what we should do when we have a test that fails only on a single git version, or a subset of our supported versions. We really have three options:
- update the test to be less picky and pass across all git versions
- update the code to ensure functionality is the same across all git versions
- capture the different functionality in the test
When it comes to something like git pull --rebase
, it doesn't bother me that lazygit behaves differently depending on the git version, because:
- users on an old git version won't be surprised if lazygit does what git already does on the command line
- it would be a pain in the ass to add bespoke code getting the old git versions to behave like new git versions
So for that specific example, I'm fine with option 1 above.
And for the '--no-show-signature' example, option 2 works because it's trivial to do.
But I'd like to have a plan for when we do need to invoke option 3 i.e. we come across functionality that we really do want to test, where older versions behave differently or not at all (e.g. we just show a 'this feature is not supported on your git version, please update' alert panel).
For this, a couple options come to mind:
a) test-level separations: specify in the test which git versions the test is expected to pass on (and create a separate test for the other versions)
b) assertion-level separations: within the test, do something like:
if t.GitVersion("> 2.20") {
// assert foo
else {
// assert bar
}
I can imagine both test-level separations and assertion-level separations being needed at some point, but I imagine that assertion-level separations will be more common.
With all that said, what are your thoughts on adding some way to check the git version from within a test, so that we can capture differences across versions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be useful to keep differences in behavior between Git versions in the test code.
It allows implementers to pay more attention to Git's behavior, and it may make it easier to determine the cause of test failures.
a)
could be achieved with NewIntegrationTestArgs.Skip
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an experiment, I tried to make the integration test move_to_earlier_commit.go
pass with any git version (it fails because of --empty=keep
). It would be possible, but require a bit of work, and I'm not sure it's worth it. On the other hand, not having the test to prove that the feature works at all in earlier git versions would also be a shame. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A rough version of that experiment is here: stefanhaller@2878ef2. Not really pretty...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great to make some progress with this. What do you both think about the experiment above?
For an upcoming PR I am in the situation again that I need version-specific integration tests. In this case I need to do a git rebase -i --update-refs
, which is only available from 2.38 on. I don't see any other way than to disable that test for earlier versions. Not sure how to do that, the Skip
property seems to accept only literal bools right now. Should we add a new MinGitVersion
property to NewIntegrationTestArgs
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stefanhaller How about changing Skip
to func(...) bool
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reckon we add a new property to NewIntegrationTestArgs
as @stefanhaller suggests. I'm thinking the field would be GitVersion
where the value would be a GitVersionRestriction
struct instance that can be constructed with a method e.g. GreaterThan("2.1.1")
or LessThan("2.1.1")
, or Between("2.1.1", "2.1.4")
or Include("2.4.1", "2.4.2", "2.4.3")
or Exclude(...)
. That should give us the flexibility we want. What do we think about that?
We've got existing code in pkg/commands/git_commands/version.go
we can make use of for this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added something like this in the PR where I needed it, see 01d76d2. I only implemented GreaterThan
, LessThan
, and Include
for now; we can add others when we need them, but I kind of doubt we will.
Actually I chose slightly different names, as I think in practice you'll want GreaterThanOrEqual
in most cases. I found that a bit unwieldy, so I chose From
and Before
instead. I'm a bit unhappy about global functions with such generic names, but it does look good at the call site. 😄
f8ea033
to
eea16a7
Compare
Nice work @Ryooooooga . My main hesitation here is that if a given git version fails, it might not be obvious why, and it would be good to fix it locally. If we were to use pre-built docker containers on CI, we could use the same image to be guaranteed to reproduce the issue locally. If we don't use docker, then we'll still need some way to go about reproducing locally (we could avoid docker on CI but then have some dockerfiles in the repo for local use, for example). What are your thoughts? |
85231b9
to
ada5014
Compare
@jesseduffield I created a Docker image for local integration_test: Ryooooooga#4 |
ada5014
to
128e3f1
Compare
.github/workflows/ci.yml
Outdated
curl -sL "https://mirrors.edge.kernel.org/pub/software/scm/git/git-${{matrix.git-version}}.tar.xz" -o - | tar xJ -C "$HOME" | ||
&& cd "$HOME/git-${{matrix.git-version}}" | ||
&& ./configure | ||
&& make -j8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does the -j8 refer to here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot that the -m
option is optional, although it specifies the number of builds in parallel.
.github/workflows/ci.yml
Outdated
&& ./configure | ||
&& make -j8 | ||
- name: Install Git ${{matrix.git-version}} | ||
run: sudo make -C "$HOME/git-${{matrix.git-version}}" -j8 install |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we also restrict this step to only run if there was a cache miss?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry it took me so long to review this :) Looking good
The test diff --git a/pkg/integration/tests/patch_building/apply_in_reverse_with_conflict.go b/pkg/integration/tests/patch_building/apply_in_reverse_with_conflict.go
index 04d160a0..ebb84fbf 100644
--- a/pkg/integration/tests/patch_building/apply_in_reverse_with_conflict.go
+++ b/pkg/integration/tests/patch_building/apply_in_reverse_with_conflict.go
@@ -51,8 +51,7 @@ var ApplyInReverseWithConflict = NewIntegrationTest(NewIntegrationTestArgs{
t.ExpectPopup().Alert().
Title(Equals("Error")).
- Content(Contains("Applied patch to 'file1' with conflicts.").
- Contains("Applied patch to 'file2' cleanly.")).
+ Content(Contains("Applied patch to 'file1' with conflicts.")).
Confirm()
t.Views().Files(). |
128e3f1
to
dfed279
Compare
dfed279
to
a761f75
Compare
a761f75
to
c90d59b
Compare
c90d59b
to
0bb767f
Compare
e711ea3
to
28e8e78
Compare
318c416
to
5f1786d
Compare
@Ryooooooga Do you have time to pick this up again? We found another regression with an older git version (#2745), and this PR would have caught it. It would be so cool to have this on master. Let me know if you don't have time, I would consider taking it on in that case. |
Since I didn't hear back, I went ahead and made my own version of this: #2754. It uses a very similar approach as this PR, but it's also different enough that it's worth re-reviewing thoroughly. |
#2754 is approved so I'll close this off. But thanks for laying the groundwork @Ryooooooga ! |
Run integration tests with various different git versions, more or less randomly picked from our range of supported versions. Based on @Ryooooooga's work in #2459, but also restructured a bit. All tests pass for all git versions, but only after cherry-picking #2747. I decided to go with @Ryooooooga's approach and do it without using docker. I also didn't use docker locally; to reproduce the various failures that I had to fix, I simply installed the respective git versions locally and used something like `PATH=~/git-versions/2.25.1/bin:$PATH ./scripts/run_integration_tests.sh`.
#2456
although not in Docker
go run scripts/cheatsheet/main.go generate
)docs/Config.md
) have been updated if necessary