Skip to content

Conversation

@Konboi
Copy link
Contributor

@Konboi Konboi commented Jul 23, 2025

To Enable PTS v2 Support

  • Add logic to check whether PTS v2 is enabled

  • When PTS v2 is enabled and no input is provided, enable Zero Input Subset (ZIS) by default

  • If ZIS has not been computed, automatically list files that look like test files

  • Add --get-tests-from-guess option

@Konboi Konboi force-pushed the subset-file-auto-collection branch from f914855 to 9a8d922 Compare July 24, 2025 00:41
@Konboi Konboi force-pushed the subset-file-auto-collection branch from 9a8d922 to d9641c3 Compare July 24, 2025 08:44
@Konboi Konboi requested a review from Copilot July 24, 2025 08:52
@launchable-app

This comment has been minimized.

This comment was marked as outdated.

@Konboi Konboi force-pushed the subset-file-auto-collection branch 3 times, most recently from 190590d to 26e857b Compare July 25, 2025 01:17
@Konboi Konboi requested a review from Copilot July 25, 2025 01:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR enables PTS (Predictive Test Selection) v2 functionality by detecting when a workspace is in "HANDS_ON_LAB_V2" state and implementing fallback behavior for automatic test collection when no tests are provided.

Key changes include:

  • Added workspace state caching and PTS v2 detection in the Launchable client
  • Implemented automatic test file collection using git ls-files when subset input is empty in PTS v2 mode
  • Refactored subset logic to handle multiple API requests with fallback behavior

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
launchable/utils/launchable_client.py Adds workspace state caching and PTS v2 detection method
launchable/commands/subset.py Implements automatic test collection and refactors subset request handling with SubsetResult class
tests/commands/test_subset.py Adds test coverage for PTS v2 behavior with multiple API requests

@Konboi Konboi force-pushed the subset-file-auto-collection branch from 26e857b to 707f0c1 Compare July 25, 2025 02:38
@Konboi Konboi changed the title To enable PTS v2 for PTS v2 Jul 25, 2025
@Konboi Konboi marked this pull request as ready for review July 25, 2025 03:06
@Konboi Konboi requested review from kohsuke and ono-max July 25, 2025 03:06
@ono-max
Copy link
Contributor

ono-max commented Jul 25, 2025

@Konboi

Is this an urgent PR? Can I review this PR in the next week?

@Konboi
Copy link
Contributor Author

Konboi commented Jul 25, 2025

@ono-max You can review this PR in the next week. Thanks

If the zero input subset response is empty and the workspace is enabled to PTS v2,
CLI will try to collect the test files automatically, and request the subset again.
"""
if client.is_enabled_pts_v2() and self.is_get_tests_from_previous_sessions and len(subset_result.subset) == 0:
Copy link
Contributor

Choose a reason for hiding this comment

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

len(subset_result.subset) == 0 test is unnerving because an empty list can be a valid response, and nothing otherwise indicates that the empty list carries this special meaning that triggers this special "let's look for what looks like tests" behavior.

I'm not sure how best to fix this. I'm now also thinking test listed like this are unlikely to be good enough for the CI process, it's only good for local examination of PTS, so I'm also wondering how best to balance that as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm now tentatively thinking defining a dedicated option to collect tests from git ls-files is better. It avoids surprises, it makes the code cleaner, and it avoids the abstraction leak of "HANDS_ON_LAB_V2" workspace state.

More concretely, my proposal is to define --guess-tests (or maybe --get-tests-from-guess to signal the fact that it's mutually exclusive with other --get-tests-...) and do local test guess scan if and only if this flag is given.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm now tentatively thinking defining a dedicated option to collect tests from git ls-files is better. It avoids surprises, it makes the code cleaner, and it avoids the abstraction leak of "HANDS_ON_LAB_V2" workspace state.

More concretely, my proposal is to define --guess-tests (or maybe --get-tests-from-guess to signal the fact that it's mutually exclusive with other --get-tests-...) and do local test guess scan if and only if this flag is given.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As far as I remember, the story we discussed was as follows:

  1. If PTS v2 is enabled for the workspace and no input is provided, the Zero Input Subset (ZIP) is enabled.
  2. If there is no data available for ZIS, the server returns an error
  3. As a fallback, files that look like tests are automatically detected.

If the case where --get-tests-from-guess is enabled, what would the flow like?

  1. Automatically detect files that look like tests
  2. Request a subset used by 1.

Would this mean the ZIS flow is skipped entirely?

Copy link
Contributor Author

@Konboi Konboi Jul 29, 2025

Choose a reason for hiding this comment

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

We discussed it directly and decided to introduce a new option, --get-tests-from-guess without any fallback behavior

state = self._get_workspace_state()
return state.get('fail_fast_mode', False)

def is_enabled_pts_v2(self) -> bool:
Copy link
Contributor

Choose a reason for hiding this comment

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

is_pts_v2_enabled would be grammatically correct

Copy link
Contributor

@ono-max ono-max left a comment

Choose a reason for hiding this comment

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

Although there are some comments from KK, you changed based on my comments. So, I'll approve this PR not to block you.

Comment on lines +653 to +654
original_subset = subset_result.subset
original_rest = subset_result.rest
Copy link
Contributor

Choose a reason for hiding this comment

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

This code is rather unnerving in so many ways:

  • The name 'original_xyz' suggests this variable will be mutated later, and yet somehow we still need to maintain the distinction (which suggests leaky abstraction -- why are we needing to mutate this, and why do we need to tell them apart)?
  • Yet the list is not copied, which suggests the mutation code will not just manipulate the list, but rather it clones or creates a whole new list.
  • And yet no such mutation seems to be happening later.

I'm currently guessing this is just a refactoring remnant. If so, let's remove this. If not, please share with me the motivation behind this, so that I can work on the follow-up PR to do it differently.


def is_enabled_pts_v2(self) -> bool:
state = self._get_workspace_state()
return state.get('state', "") == "HANDS_ON_LAB_V2"
Copy link
Contributor

Choose a reason for hiding this comment

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

I mentioned "the abstraction leak of HANDS_ON_LAB_V2", let me expand it here a bit.

"PTS v2" is amorphous project. So when you define a flag like this, I worry about how the client of this code can easily drift off from what the server side means with this flag. More so if you think about the fact that the CLI is a packaged software and therefore it's more "stiff" than the server side code, meaning we have less control over how long it lives.

And this starts to feel even more out of place if you think about the fact that the test selection logic is really supposed to be a black box from the CLI perspective anyway. Where and why would the CLI need to know how exactly our service is selecting tests? It asks for scrutiny.

AFAICT, the only reason this is needed is in order to trigger implicit local test collection behavior. For mostly unrelated reasons I'm now thinking that's problematic anyway. So I'm inclined to suggest we shouldn't have the is_enabled_pts_v2 method.

If we do decide to keep, I'd advise against making this another constant to the broken 'workspace state' enum. Enum means those state constants are mutually exclusive, but this one is not -- an ACTIVE_PAYING workspace might have a V2 PTS, and similarly PUBLIC_OSS_PROJECT might have a V2 PTS.

(For that matter, I think we better clarify the meaning of "workspace state". ARCHIVED is probably not an enum state either)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks.
I think using an enum is fine, but I believe it would be better to have the value returned from the server, like isFailFastMode. So I’ll fix it in this PR

Copy link
Contributor

@kohsuke kohsuke left a comment

Choose a reason for hiding this comment

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

I left so many comments, but but in hindsight, maybe it's me wondering down a tangential path.

In the interest of not blocking the critical effort, I think the only clear "bug" is the one comment around subprocess.CalledProcessError, and I can work on a separate PR to try to improve the relevant code a bit.

@Konboi Konboi requested a review from kohsuke July 29, 2025 04:33
@Konboi
Copy link
Contributor Author

Konboi commented Jul 29, 2025

@kohsuke I fixed some points based on your feedback. Could you review again, just in case?
Especially this part #1081 (comment)

kohsuke added 3 commits July 29, 2025 10:17
This logic should be promoted further up ideally.
This is a configuration error so I think it makes sense to make this
fatal.
kohsuke added 3 commits July 29, 2025 13:31
- Emitting a warning is a common pattern. This needs to be promoted up.
- `git ls-files` can result in other types of exceptions thrown
- Not finding anything in `git ls-files` should trigger a warning
@kohsuke kohsuke force-pushed the subset-file-auto-collection branch from fdaafc4 to 9ca63ee Compare July 29, 2025 20:31
tracking_client.send_error_event(event_name=event, stack_trace=msg)
sys.exit(1)

if is_get_tests_from_guess and is_get_tests_from_previous_sessions:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

nice 👍

if self.input_given:
print_error_and_die("ERROR: Given arguments did not match any tests. They appear to be incorrect/non-existent.", Tracking.ErrorEvent.USER_ERROR) # noqa E501
if client.is_enabled_pts_v2():
if client.is_pts_v2_enabled():
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because we decided to add --get-tests-from-guess option instead auto enabling the zero input subset with fallback behavior #1081 (comment)

Also, I removed the code 5f1c058#diff-4c62e35fb4e3b2b6bff8593107cdddd1fd47eff90293edc9d838c9b2f3cff94aL603-L605 but it has reverted

I'll remove this if condition.

@sonarqubecloud
Copy link

@Konboi Konboi merged commit 6995783 into main Jul 30, 2025
15 checks passed
@Konboi Konboi deleted the subset-file-auto-collection branch July 30, 2025 03:43
@github-actions github-actions bot mentioned this pull request Jul 30, 2025
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.

4 participants