Skip to content

[llvm-lit] Print environment variables when using env without subcommand #98414

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 25 commits into from
Aug 29, 2024

Conversation

Harini0924
Copy link
Contributor

@Harini0924 Harini0924 commented Jul 10, 2024

This patch addresses an issue with lit's internal shell when env is without any arguments, it fails with exit code 127 because env requires a subcommand. This patch addresses the issue by encoding the command to properly return environment variables even when no arguments are provided.

The error occurred when running the command
LIT_USE_INTERNAL_SHELL=1 ninja check-llvm.

fixes: #102383
This is part of the test cleanups proposed in the RFC: [RFC] Enabling the Lit Internal Shell by Default

Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be
notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write
permissions for the repository. In which case you can instead tag reviewers by
name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review
by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate
is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@Harini0924
Copy link
Contributor Author

CC: @ilovepi @petrhosek

@llvmbot
Copy link
Member

llvmbot commented Jul 10, 2024

@llvm/pr-subscribers-testing-tools

Author: None (Harini0924)

Changes

When executing not --crash env in lit's internal shell without any arguments, it fails with exit code 127 because env requires a subcommand. This patch addresses the issue by encoding the command to properly return environment variables even when no arguments are provided.


Full diff: https://github.com/llvm/llvm-project/pull/98414.diff

1 Files Affected:

  • (modified) llvm/utils/lit/lit/TestRunner.py (+2-1)
diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py
index da7fa86fd3917..8f0cd801ae9ff 100644
--- a/llvm/utils/lit/lit/TestRunner.py
+++ b/llvm/utils/lit/lit/TestRunner.py
@@ -743,7 +743,8 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):
                     cmd_shenv = ShellEnvironment(shenv.cwd, shenv.env)
                 args = updateEnv(cmd_shenv, args)
                 if not args:
-                    raise InternalShellError(j, "Error: 'env' requires a" " subcommand")
+                    # Return the environment variables if no argument is provided 
+                    return {key: value for key, value in cmd_shenv.env.items()}
             elif args[0] == "not":
                 not_args.append(args.pop(0))
                 not_count += 1

Copy link
Contributor

@ilovepi ilovepi left a comment

Choose a reason for hiding this comment

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

LGTM, but let’s modify the commit message slightly. First, it’s not really important to include the context about the “not —crash” bits. Additionally, the precise error code isn’t important only that the command failed.

This patch is really about the internal shell’s support for printing the environment as output. So let’s trim it down to just those bits.

Copy link
Collaborator

@jh7370 jh7370 left a comment

Choose a reason for hiding this comment

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

What's the purpose of doing not --crash env? That sounds to me like you're trying to show that the internal lit env doesn't crash?

Assuming it is needed, shouldn't there be a test for this?

Copy link

github-actions bot commented Jul 11, 2024

✅ With the latest revision this PR passed the Python code formatter.

@ilovepi
Copy link
Contributor

ilovepi commented Jul 11, 2024

What's the purpose of doing not --crash env? That sounds to me like you're trying to show that the internal lit env doesn't crash?

That comes from https://github.com/llvm/llvm-project/blob/main/llvm/test/tools/not/disable-symbolization.test, so I'd guess its more about not than env. I'd hazard that test could be rewritten w/o env, but I think some other tests outside of llvm also rely on this behavior.

Assuming it is needed, shouldn't there be a test for this?

Actually yes, I agree. I confused this case w/ another one that was NFC.

@Harini0924, let's add a test for the new env behavior. Those should be updated in https://github.com/llvm/llvm-project/blob/main/llvm/utils/lit/tests/shtest-env.py. The fact that that test still seems to be passing means that we're not handling this case correctly. Likely it still fails, but does that differently.

Copy link
Contributor

@ilovepi ilovepi left a comment

Choose a reason for hiding this comment

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

I should have checked a bit more closely when reviewing this the first time. I assumed when the LLVM tests had passed, that this change was doing the right thing, but as pointed out by other reviewers, it is not.

So, please add some testing for env, and instead of returning the dictionary, we can just call a function to correctly print the environment instead.

@Harini0924 Harini0924 marked this pull request as draft July 17, 2024 23:00
When executing not --crash env without any arguments,
it fails with exit code 127 because env reuires a
subcommand. This path addresses the issue by encoding
the command to properly return environment variables
even when no arguments are provided.
@Harini0924 Harini0924 force-pushed the llvm_env branch 2 times, most recently from 920d5b1 to bd4f897 Compare July 18, 2024 06:50
This patch addresses an issue where calling env without any arguments incorrectly returns
a "requires subcommand" message. The patch modifies the env command to properly display
the current environment variables even when no arguments are provided. Additionally,
the test cases have been updated: instead of returning an error, the tests now pass
and check if the environment variables are output correctly.
This patch addresses an issue where calling env without any arguments incorrectly returns
a "requires subcommand" message. The patch modifies the env command to properly display
the current environment variables even when no arguments are provided. Additionally, the
test cases have been updated: instead of returning an error, the tests now pass and check
if the environment variables are output correctly.
This patch addresses an issue where calling env without any arguments incorrectly returns a "requires subcommand" message. The patch modifies the env command to properly display the current environment variables even when no arguments are provided. Additionally, the test cases have been updated: instead of returning an error, the tests now pass and check if the environment variables are output correctly.
This patch addresses an issue where calling env without any arguments incorrectly
returns a "requires subcommand" message. The patch modifies the env command to
properly display the current environment variables even when no arguments are provided.
Additionally, the test cases have been updated: instead of returning an error, the tests
now pass and check if the environment variables are output correctly.
This patch addresses an issue where calling env without any arguments incorrectly returns
a "requires subcommand" message. The patch modifies the env command to properly display
the current environment variables even when no arguments are provided. Additionally,
the test cases have been updated: instead of returning an error, the tests now pass
and check if the environment variables are output correctly.
Copy link
Contributor

@ilovepi ilovepi left a comment

Choose a reason for hiding this comment

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

Thanks for adding the tests. I think this is pretty close for me, but I'm still a bit unsure about the early return. @petrhosek brought up a technical point about that, and I think we should determine if those are still a problem before landing this as is. If you can, provide some context on what you found, that may help us make that determination faster.

@ilovepi
Copy link
Contributor

ilovepi commented Jul 19, 2024

@jh7370 I think we have some other tests that have an EMPTY suffix, such as

I suppose we should update those too(separately).

@Harini0924 Harini0924 marked this pull request as ready for review July 19, 2024 21:54
Copy link
Contributor

@ilovepi ilovepi left a comment

Choose a reason for hiding this comment

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

LGTM as long as bots are happy. I'll land this for you once those pass and @jh7370 is satisfied.

Copy link
Collaborator

@jh7370 jh7370 left a comment

Choose a reason for hiding this comment

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

This still hasn't been run through the python code formatter (and there's still trailing whitespace on the line I highlighted before).

See also https://llvm.org/docs/CodingStandards.html#python-version-and-source-code-formatting.

Copy link
Collaborator

@jh7370 jh7370 left a comment

Choose a reason for hiding this comment

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

The coding standard I linked last time say only to modify the bits of code you touch in the PR, not the whole files. It looks like some of these files aren't even touched by this PR...

(Sorry for being fussy)

@Harini0924
Copy link
Contributor Author

@jh7370 I've fixed the missing space in env-args-none.txt. Is there anything else I should adjust or add? Please let me know.

Updated test cases to use `CHECK-NOT: # error`.
@Harini0924
Copy link
Contributor Author

Harini0924 commented Aug 7, 2024

@jh7370 @arichardson I've changed # CHECK-NOT: {{^[^#]}} to # CHECK-NOT: # error: for the tests I modified. To maintain consistency across the whole file, should update the other passing tests to use # CHECK-NOT: # error: as well?

@jh7370
Copy link
Collaborator

jh7370 commented Aug 8, 2024

@jh7370 @arichardson I've changed # CHECK-NOT: {{^[^#]}} to # CHECK-NOT: # error: for the tests I modified. To maintain consistency across the whole file, should update the other passing tests to use # CHECK-NOT: # error: as well?

Generally, I'd avoid making consistency changes in the same PR, and make them in a follow-up instead.

That being said, I'm wondering if the intent of the other lines wasn't to check specifically for an error, but rather to check for any executed command output at all? Unfortunately, I'm not really familiar with this test or its background. I'd be reluctant to change what the test is really checking for without understanding its purpose.

@Harini0924
Copy link
Contributor Author

@jh7370 To clarify the changes I made: Originally, when the tests were failing, there was a check for errors using the line # CHECK: # error: command failed with exit status: {{.*}}. However, since the tests have been modified and are now passing, I replaced that check with # CHECK-NOT: {{^[^#]}}. This change reflects the fact that the tests are no longer expecting an error, but rather verifying that no unexpected output is generated.

Given this, I think it makes sense to maintain the original format for passing tests, which is # CHECK-NOT: {{^[^#]}}, instead of # CHECK-NOT: # error:. Does this approach make sense to you, or do you have any thoughts on changing this? If this makes sense, I can revert the last commit and use # CHECK-NOT: {{^[^#]}} consistently for the tests that pass. Please let me know if I should clarify anything further.

@jh7370
Copy link
Collaborator

jh7370 commented Aug 12, 2024

@jh7370 To clarify the changes I made: Originally, when the tests were failing, there was a check for errors using the line # CHECK: # error: command failed with exit status: {{.*}}. However, since the tests have been modified and are now passing, I replaced that check with # CHECK-NOT: {{^[^#]}}. This change reflects the fact that the tests are no longer expecting an error, but rather verifying that no unexpected output is generated.

Given this, I think it makes sense to maintain the original format for passing tests, which is # CHECK-NOT: {{^[^#]}}, instead of # CHECK-NOT: # error:. Does this approach make sense to you, or do you have any thoughts on changing this? If this makes sense, I can revert the last commit and use # CHECK-NOT: {{^[^#]}} consistently for the tests that pass. Please let me know if I should clarify anything further.

Just spelling out what the regex means, because I've tripped myself up at least twice trying to interpret it. ^ means "start of line". [^#] means "any character except #. Combined they mean "match a non-empty line that does not start with #". CHECK-NOT instructs FileCheck to fail if it sees the specified between the previous thing it matched and the next thing it matches, so the combined effect is to fail the test if, between the previous and next patterns, a non-empty line without a leading # appears. In other words, it will NOT fail if it sees e.g. # error: in the output, because of the leading # (and based on the checks elsewhere in the file, I assume that is indeed the format that errors will be printed in). Could somebody confirm that I'm not making a mistake?

@Harini0924, if you didn't have any other tests to base things on, and you wanted to write this specific test completely from scratch, what would your CHECK lines look like? The way you've been replying, I feel like you don't really have a clear idea of what you are trying to achieve, which makes me nervous. On the other hand, maybe it's just a communication thing.


Unrelated, but "Resolve env subcommand required error" isn't really describing what this patch does in a useful manner. I think the key thing is that you're changing env without subcommands to print the environment variables, so I'd change this to "
[llvm-lit] Print environment variables when using env without subcommand".

@Harini0924 Harini0924 changed the title [llvm-lit] Resolve env subcommand required error [llvm-lit] Print environment variables when using env without subcommand". Aug 12, 2024
@Harini0924 Harini0924 changed the title [llvm-lit] Print environment variables when using env without subcommand". [llvm-lit] Print environment variables when using env without subcommand Aug 12, 2024
@RoboTux
Copy link
Contributor

RoboTux commented Aug 12, 2024

Just spelling out what the regex means, because I've tripped myself up at least twice trying to interpret it. ^ means "start of line". [^#] means "any character except #. Combined they mean "match a non-empty line that does not start with #". CHECK-NOT instructs FileCheck to fail if it sees the specified between the previous thing it matched and the next thing it matches, so the combined effect is to fail the test if, between the previous and next patterns, a non-empty line without a leading # appears. In other words, it will NOT fail if it sees e.g. # error: in the output, because of the leading # (and based on the checks elsewhere in the file, I assume that is indeed the format that errors will be printed in). Could somebody confirm that I'm not making a mistake?

That would be my reading as well. Therefore I think "CHECK-NOT: # error: " is a better test but I think we should also split Inputs/shtest-env/* into a positive and negative tests and split shtest-env.py in two accordingly. This would allow to use RUN: %{lit} instead of RUN: not %{lit} thus guaranteeing that lit does not return an error.

@Harini0924
Copy link
Contributor Author

Harini0924 commented Aug 12, 2024

@jh7370 @RoboTux Thank you for the feedback earlier. To clarify, I'm implementing the tests by splitting them into two separate test files—one for positive tests and one for negative tests.

  • Positive Tests: In the positive test file, I’m removing not from the RUN line (e.g., # RUN: %{lit} -a -v %{inputs}/shtest-env-positive | FileCheck -match-full-lines %s) and using # CHECK-NOT: # error: to ensure no errors occur.

  • Negative Tests: In the negative test file, I will keep not in the RUN line (e.g., # RUN: not %{lit} -a -v %{inputs}/shtest-env-negative | FileCheck -match-full-lines %s) and will use # CHECK: # error: command failed with exit status: {{.*}}, since these tests are expected to fail and will have an error line.

Additionally, I will be splitting tests/Inputs/shtest-env into tests/Inputs/shtest-env-positive and tests/Inputs/shtest-env-negative, with each containing their respective passing and failing tests.

Does this approach align with what you were suggesting? I want to make sure I'm on the right track.

… test files

Created `shtest-env-positive.py` for positive tests, removing `not` from the RUN
line and using `CHECK-NOT: # error:` to ensure no errors occur. Created `shtest-env-negative.py`
for negative tests, keeping `not` in the RUN line and using `CHECK: # error: command failed with
exit status: {{.*}}` to verify expected failures. Split `tests/Inputs/shtest-env` into
`tests/Inputs/shtest-env-positive` and `tests/Inputs/shtest-env-negative`, organizing
the respective passing and failing tests into their appropriate directories.
As part of the recent restructuring, the `shtest-env` directory
has been split into separate `shtest-env-positive` and
`shtest-env-negative` directories to better organize the
test cases. This commit removes the now obsolete files
from the original `shtest-env` directory that have been
migrated to the new structure.
@jh7370
Copy link
Collaborator

jh7370 commented Aug 14, 2024

I'd like @RoboTux's feedback on the latest version before I do another round of reviewing this myself.

@RoboTux
Copy link
Contributor

RoboTux commented Aug 14, 2024

@jh7370 @RoboTux Thank you for the feedback earlier. To clarify, I'm implementing the tests by splitting them into two separate test files—one for positive tests and one for negative tests.

* **Positive Tests:**  In the positive test file, I’m removing `not` from the RUN line (e.g., `# RUN: %{lit} -a -v %{inputs}/shtest-env-positive | FileCheck -match-full-lines %s`) and using `# CHECK-NOT: # error: `to ensure no errors occur.

* **Negative Tests:**  In the negative test file, I will keep `not` in the RUN line (e.g., `# RUN: not %{lit} -a -v %{inputs}/shtest-env-negative | FileCheck -match-full-lines %s`) and will use `# CHECK: # error: command failed with exit status: {{.*}}`, since these tests are expected to fail and will have an error line.

Additionally, I will be splitting tests/Inputs/shtest-env into tests/Inputs/shtest-env-positive and tests/Inputs/shtest-env-negative, with each containing their respective passing and failing tests.

Does this approach align with what you were suggesting? I want to make sure I'm on the right track.

Yes, that's exactly it. I'm not sure CHECK-NOT: #error is necessary for the positive case because I would expect lit to fail if any error is thrown but it cannot hurt.

Copy link
Collaborator

@jh7370 jh7370 left a comment

Choose a reason for hiding this comment

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

Couple more suggestions, but this basically looks good.

I'm not convinced the # error check not lines are needed, but I'm also not opposed to them.

This patch removes the print_environment.py file, which was previously
used to print environment variables in the format KEY=VALUE. The tests
have been refactored to directly use the env command, with the output
being validated using FileCheck. Comments were updated to use ## for
better readability, and the test cases were rewritten to ensure
consistency.
Added a comment at the top of every file that I modified explaining the
general purpose of the tests in the file.
Copy link
Collaborator

@jh7370 jh7370 left a comment

Choose a reason for hiding this comment

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

Some nits, but nearly there.

@@ -1,3 +1,5 @@
## Tests the env command's ability to handle setting, unsetting, and mixing environment variables.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nearly there, but now I'm looking at the test file name. What is significant about the "none" part of the file name? I'd interpret it to mean "env with no args", but most of the test cases in this file have at least one argument.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Please don't resolve comment threads I've started, even if you think you've addressed my comment. My comment was about the file name, which to me looks incorrect. What does "args-none" mean in the file name? -u FOO or whatever is not "no arguments".

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'm sorry for the confusion. You're right; the name "args-none" doesn't accurately reflect the content of the test, especially since the file includes scenarios with arguments like -u FOO and others. A more suitable name could be something like env-var-handling.txt or env-command-tests.txt to broadly cover all the scenarios tested in the file. Do either of these work, or do you have any other suggestions?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think probably env-no-subcommand.txt would be the name that best-conveys its meaning. It looks like the common factor in these tests is that no additional process exists that is run with the env-specified variables.

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 agree env-no-subcommand.txt is a better file name. I have renamed env-args-none.txt to env-no-subcommand.txt in my recent commit.

@Harini0924
Copy link
Contributor Author

@jh7370 Are there any other changes I need to make?

@@ -6,32 +6,32 @@
# NO-ARGS: BAR=2
# NO-ARGS: FOO=1
# NO-ARGS: QUX=3

Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit, you've added trailing whitespace again here and on many other lines in this file. Please fix!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Collaborator

@jh7370 jh7370 left a comment

Choose a reason for hiding this comment

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

LGTM, assuming the pre-merge checks pass.

@Harini0924 Harini0924 merged commit 1783924 into llvm:main Aug 29, 2024
8 checks passed
Copy link

@Harini0924 Congratulations on having your first Pull Request (PR) merged into the LLVM Project!

Your changes will be combined with recent changes from other authors, then tested by our build bots. If there is a problem with a build, you may receive a report in an email or a comment on this PR.

Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail here.

If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of LLVM development. You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are working as expected, well done!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[llvm-lit] The lit internal shell doesn’t support env command without any arguments
7 participants