-
Notifications
You must be signed in to change notification settings - Fork 1
fix/manifest-tag #319
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
base: main
Are you sure you want to change the base?
fix/manifest-tag #319
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -401,13 +401,52 @@ func TestConvertTo_LegacyOverridesManifestUnavailable(t *testing.T) { | |
| "env": map[string]interface{}{"API_VAR": "1"}, | ||
| }, | ||
| })) | ||
| // A manifest fetch failure must never fail conversion: global env still | ||
| // converts, per-app extraction is skipped. | ||
| // Converting anyway would drop api's env while reporting success, so the | ||
| // write is rejected instead. | ||
| err := src.ConvertTo(dst) | ||
| require.Error(t, err) | ||
| require.Contains(t, err.Error(), "resolve server manifest") | ||
| require.Contains(t, err.Error(), testLegacyVersion) | ||
| require.Contains(t, err.Error(), "registry unreachable") | ||
| } | ||
|
|
||
| // TestConvertTo_LegacyOverridesManifestUnavailableNoAppSections: with nothing | ||
| // per-application to lose, an unresolvable manifest is still fatal — the | ||
| // manifest decides what counts as an application, so we can't know there was | ||
| // nothing to map. | ||
| func TestConvertTo_LegacyOverridesManifestUnavailableNoAppSections(t *testing.T) { | ||
| SetConversionManifestGetter(func(_ context.Context, _, _ string) (serverManifest.Manifest, error) { | ||
| return serverManifest.Manifest{}, errors.New("registry unreachable") | ||
| }) | ||
| t.Cleanup(disableConversionManifestFetch) | ||
|
|
||
| dst := &appsv2.WeightsAndBiases{} | ||
| src := newV1(withVersion(map[string]interface{}{ | ||
| "global": map[string]interface{}{"host": "http://wandb.example.com"}, | ||
| })) | ||
| require.Error(t, src.ConvertTo(dst)) | ||
| } | ||
|
|
||
| // TestConvertTo_NoVersionSkipsManifestFetch: without a version there is nothing | ||
| // to resolve, so conversion proceeds and global env still converts. | ||
| func TestConvertTo_NoVersionSkipsManifestFetch(t *testing.T) { | ||
| var calls atomic.Int32 | ||
| SetConversionManifestGetter(func(_ context.Context, _, _ string) (serverManifest.Manifest, error) { | ||
| calls.Add(1) | ||
| return serverManifest.Manifest{}, errors.New("registry unreachable") | ||
| }) | ||
| t.Cleanup(disableConversionManifestFetch) | ||
|
|
||
| dst := &appsv2.WeightsAndBiases{} | ||
| src := newV1(map[string]interface{}{ | ||
| "global": map[string]interface{}{ | ||
| "env": map[string]interface{}{"HTTP_PROXY": "http://proxy"}, | ||
| }, | ||
| }) | ||
| require.NoError(t, src.ConvertTo(dst)) | ||
|
|
||
| overrides := dst.Spec.Wandb.LegacyOverrides | ||
| require.Contains(t, overrides, appsv2.LegacyOverridesGlobalKey) | ||
| require.NotContains(t, overrides, "api") | ||
| require.Contains(t, dst.Spec.Wandb.LegacyOverrides, appsv2.LegacyOverridesGlobalKey) | ||
| require.Equal(t, int32(0), calls.Load(), "no version means no manifest fetch") | ||
|
Comment on lines
446
to
+449
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Assert the converted global environment value. The key-presence assertion passes if conversion creates an empty global override. Assert that 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| func TestConvertTo_LegacyOverridesManifestFailureCooldown(t *testing.T) { | ||
|
|
@@ -426,8 +465,8 @@ func TestConvertTo_LegacyOverridesManifestFailureCooldown(t *testing.T) { | |
| "env": map[string]interface{}{"API_VAR": "1"}, | ||
| }, | ||
| })) | ||
| require.NoError(t, src.ConvertTo(dst)) | ||
| require.NotContains(t, dst.Spec.Wandb.LegacyOverrides, "api") | ||
| // Every attempt fails, but from the cached failure rather than a refetch. | ||
| require.Error(t, src.ConvertTo(dst)) | ||
| } | ||
|
|
||
| require.Equal(t, int32(1), calls.Load(), "repeat conversions within the cooldown must not retry the fetch") | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -448,6 +448,18 @@ func validateWandbSpec(wandb *appsv2.WeightsAndBiases) field.ErrorList { | |||||||||||||||||||||||||||||||||||||||||||
| )) | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| // v1 installs commonly ran app.image.tag=latest, which conversion copies | ||||||||||||||||||||||||||||||||||||||||||||
| // verbatim. No server-manifest artifact is published under a mutable tag, so | ||||||||||||||||||||||||||||||||||||||||||||
| // the manifest lookup fails and the whole reconcile aborts. Reject it at | ||||||||||||||||||||||||||||||||||||||||||||
| // admission, where the message is actionable, instead of at reconcile time. | ||||||||||||||||||||||||||||||||||||||||||||
| if strings.TrimSpace(wandb.Spec.Wandb.Version) == "latest" { | ||||||||||||||||||||||||||||||||||||||||||||
| errors = append(errors, field.Invalid( | ||||||||||||||||||||||||||||||||||||||||||||
| field.NewPath("spec").Child("wandb").Child("version"), | ||||||||||||||||||||||||||||||||||||||||||||
| wandb.Spec.Wandb.Version, | ||||||||||||||||||||||||||||||||||||||||||||
| "must be pinned to a published server version; no server-manifest is published for the \"latest\" tag", | ||||||||||||||||||||||||||||||||||||||||||||
| )) | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+452
to
+458
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Reject or normalize whitespace around server versions. The condition trims Proposed validation+ version := strings.TrimSpace(wandb.Spec.Wandb.Version)
- if strings.TrimSpace(wandb.Spec.Wandb.Version) == "latest" {
+ if version == "latest" {
errors = append(errors, field.Invalid(
field.NewPath("spec").Child("wandb").Child("version"),
wandb.Spec.Wandb.Version,
"must be pinned to a published server version; no server-manifest is published for the \"latest\" tag",
))
+ } else if version != wandb.Spec.Wandb.Version {
+ errors = append(errors, field.Invalid(
+ field.NewPath("spec").Child("wandb").Child("version"),
+ wandb.Spec.Wandb.Version,
+ "must not contain leading or trailing whitespace",
+ ))
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| return errors | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
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.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: wandb/operator
Length of output: 50371
🏁 Script executed:
Repository: wandb/operator
Length of output: 243
🏁 Script executed:
Repository: wandb/operator
Length of output: 243
🏁 Script executed:
Repository: wandb/operator
Length of output: 8675
Use the repository suite pattern for conversion tests.
api/v1/weightsandbiases_conversion_overrides_test.gostill definesfunc TestConvertTo_...and usestesting.T/Testifyrequire, while the package has no Ginkgo suite. Rewrite these tests withfunc TestV1ConversionSuites(t *testing.T)plusRunSpecs, and replace assertions with Ginkgo/Gomega.🤖 Prompt for AI Agents
Source: Coding guidelines