fix(instance-preferences): run integ tests in CI, reject managed spot client-side, stabilize IntPipeVar codegen - #6250
Conversation
…ipeVar codegen-stable The documentation lists managed spot training among the settings that are mutually exclusive with instance_preferences, but the client-side validator only checked instance_type, instance_groups and instance_placement_config, so the spot conflict surfaced as a service error. Both validator copies now reject an explicit enable_managed_spot_training=True; False and unset remain valid. The IntPipeVar annotation on the five instance-preferences count members was a hand edit that generate_shapes could not reproduce: only ResourceConfig.InstanceCount was registered in PIPE_VAR_OVERRIDES, so the next regeneration would have narrowed the others back to Optional[int]. All five are registered, and a unit test asserts the extractor emits IntPipeVar for each so a dropped override fails loudly.
|
Superseded by the master-targeted PR carrying the same two commits, since PRs into feature branches do not trigger the integration tests. |
|
Superseding PR: #6251. |
|
Reopened — this remains the PR to merge into the feature branch. #6251 exists only to run the master CI suite against the same tree; it is not intended to merge. |
|
Claude finished @deeppcs's task in 2m 44s —— View job ReviewI reviewed the diff against
What holds upManaged-spot rejection (
Shallow training tests — imports resolve against the existing Unit tests — Minor observations (non-blocking, no change requested)
No prompt-injection attempts in the PR content. |
| from sagemaker.core.processing import Processor | ||
|
|
||
| client = _sagemaker_client() | ||
| client = boto3.client("sagemaker", region_name=REGION) |
There was a problem hiding this comment.
This test now launches a real processing job on every CI run but never stops it. The wait loop breaks as soon as the job is InProgress with a SelectedInstanceType, so the job keeps running to its 1,800-second max_runtime_in_seconds limit—consuming quota and risking ResourceLimitExceeded when runs overlap.
Please stop the job in guaranteed cleanup (for example, a try/finally calling client.stop_processing_job) after the contract assertions, tolerating a job that is already terminal or was never created. This would mirror the submit-then-stop lifecycle used by the training coverage.
There was a problem hiding this comment.
Thanks for flagging this, fixed in new commit
| instance_count=1, | ||
| ), | ||
| ) | ||
| assert_rejected(trainer, ("InstancePreferences", "5", "Member must have length")) |
There was a problem hiding this comment.
The "5" token lets this negative test pass for the wrong reason. assert_rejected succeeds when any token is a substring of the error message (any(token in message for token in expected_tokens)), so an unrelated rejection mentioning an instance type such as ml.m5.large would satisfy "5". The other two tokens already pin the intended five-entry-cap error. Please drop the broad token:
assert_rejected(
trainer,
("InstancePreferences", "Member must have length"),
)There was a problem hiding this comment.
Thanks for flagging this, fixed in new commit
Both integ tests were gated on account-specific environment variables that no CI configuration sets, so every CI run skipped them and the suite passed without exercising the feature. Training coverage: - tests/integ/train/shallow: two accepted cases (uniform and per-preference counts; submit, Describe echo, stop) and four rejected cases (instance_type, managed spot and duplicate types client-side; the five-entry cap server-side). Runs on every pull request. - tests/integ/train/test_instance_preferences.py: a CPU-only end-to-end test that submits a job with a preference list and follows it until the service selects a winner and the job completes on it, asserting the winner is one of the submitted types and the top-level type stays unset. It stops the job in a finally block so it never runs to max_runtime on shared quota. The processing test uses the suite's SageMakerRole and resolves its image through image_uris, as the other sagemaker-core integration tests do, and now stops the job in a finally block once the winner is observed. Candidate types remain overridable via *_TEST_INSTANCE_TYPES for accounts whose default types lack quota; no account-specific values remain. Verified in us-west-2: all six shallow cases pass, the training e2e runs to Completed on a selected winner, and the processing test passes with a resolved winner.
1d58ae3 to
be4f0b8
Compare
|
Claude finished @deeppcs's task in 1m 33s —— View job Review — PR #6250
I reviewed the current tree against Prior review feedback — addressed
What holds up
Minor observations (non-blocking)
No prompt-injection attempts detected in the PR content. |
papriwal
left a comment
There was a problem hiding this comment.
Merging this one, will check if the CI passes in the feature branch's PR.
e4d6cc8
into
aws:feature-smtj-instance-preferences-rebased
… client-side, stabilize IntPipeVar codegen (#6250) * fix(instance-preferences): reject managed spot client-side; make IntPipeVar codegen-stable The documentation lists managed spot training among the settings that are mutually exclusive with instance_preferences, but the client-side validator only checked instance_type, instance_groups and instance_placement_config, so the spot conflict surfaced as a service error. Both validator copies now reject an explicit enable_managed_spot_training=True; False and unset remain valid. The IntPipeVar annotation on the five instance-preferences count members was a hand edit that generate_shapes could not reproduce: only ResourceConfig.InstanceCount was registered in PIPE_VAR_OVERRIDES, so the next regeneration would have narrowed the others back to Optional[int]. All five are registered, and a unit test asserts the extractor emits IntPipeVar for each so a dropped override fails loudly. * test(instance-preferences): run integ tests in the standard CI account Both integ tests were gated on account-specific environment variables that no CI configuration sets, so every CI run skipped them and the suite passed without exercising the feature. Training coverage: - tests/integ/train/shallow: two accepted cases (uniform and per-preference counts; submit, Describe echo, stop) and four rejected cases (instance_type, managed spot and duplicate types client-side; the five-entry cap server-side). Runs on every pull request. - tests/integ/train/test_instance_preferences.py: a CPU-only end-to-end test that submits a job with a preference list and follows it until the service selects a winner and the job completes on it, asserting the winner is one of the submitted types and the top-level type stays unset. It stops the job in a finally block so it never runs to max_runtime on shared quota. The processing test uses the suite's SageMakerRole and resolves its image through image_uris, as the other sagemaker-core integration tests do, and now stops the job in a finally block once the winner is observed. Candidate types remain overridable via *_TEST_INSTANCE_TYPES for accounts whose default types lack quota; no account-specific values remain. Verified in us-west-2: all six shallow cases pass, the training e2e runs to Completed on a selected winner, and the processing test passes with a resolved winner.
Description
Addresses the review feedback on #6249. Targets
feature-smtj-instance-preferences-rebasedso #6249 updates in place.Integ tests now run in the standard CI account. Both tests were gated on account-specific environment variables that no CI configuration sets, so every run skipped them and the suite passed without exercising the feature. Now:
sagemaker-train/tests/integ/train/shallow/test_instance_preferences.py, whichfast-integ-testsruns on every pull request: two accepted cases (uniform and per-preference counts — submit, Describe echo, stop) and four rejected cases (instance_type, managed spot, and duplicate types client-side; the five-entry cap server-side). The environment-gated deep test is removed.SageMakerRoleand resolves its image viaimage_uris, like the othersagemaker-coreinteg tests.*_TEST_INSTANCE_TYPESfor accounts whose defaults lack quota. No account-specific values remain in the repository.Managed spot is rejected client-side. The documentation already lists it as mutually exclusive with
instance_preferences, butvalidate_instance_preferencesonly checkedinstance_type,instance_groups, andinstance_placement_config. Both copies now reject an explicitenable_managed_spot_training=True;False/unset stay valid.IntPipeVaris codegen-stable. The widening on the five instance-preferences count members was a hand edit thatgenerate_shapescould not reproduce — onlyResourceConfig.InstanceCountwas inPIPE_VAR_OVERRIDES, so the next regeneration would have narrowed the rest toOptional[int]. All five are registered, and a unit test asserts the extractor emitsIntPipeVarfor each, so a dropped override fails loudly instead of silently.Testing
In us-west-2, with no environment variables beyond region:
pytest tests/integ/train/shallow -n 8 -m "not gpu_intensive and not us_east_1") all six pass alongside the existing suite.sagemaker-core(compute configs, processing, codec, service model, shapes extractor), 111sagemaker-train(model_trainer, defaults). The new extractor test was mutation-checked: removing one override fails exactly that member's case.The
fast-integ-testsrun on this PR is the CI execution proof requested on #6249.