Skip to content

Commit 31bc049

Browse files
committed
Update unit tests for customizer with new config templates
Signed-off-by: Shiva Krishna, Merla <[email protected]>
1 parent 0045484 commit 31bc049

File tree

5 files changed

+561
-5
lines changed

5 files changed

+561
-5
lines changed

config/samples/nemo/latest/nemocustomizer_config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ data:
2222
targets:
2323
2424
base_model: meta/llama-3.1-8b-instruct
25-
enabled: false
25+
enabled: true
2626
model_path: llama-3_1-8b-instruct_2_0
2727
model_uri: ngc://nvidia/nemo/llama-3_1-8b-instruct-nemo:2.0
2828
@@ -49,7 +49,7 @@ data:
4949
precision: bf16-mixed
5050
5151
base_model: meta/llama-3.2-1b-instruct
52-
enabled: false
52+
enabled: true
5353
model_path: llama32_1b-instruct_2_0
5454
model_uri: ngc://nvidia/nemo/llama-3_2-1b-instruct:2.0
5555

internal/controller/nemocustomizer_controller.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -569,12 +569,19 @@ func (r *NemoCustomizerReconciler) addModelDownloadJobsConfig(ctx context.Contex
569569
"ngcAPISecretKey": n.Spec.ModelDownloadJobs.NGCSecret.Key,
570570
"ngcSecretName": n.Spec.ModelDownloadJobs.NGCSecret.Name,
571571
"ngcSecretKey": n.Spec.ModelDownloadJobs.NGCSecret.Key,
572-
"hfSecretName": n.Spec.ModelDownloadJobs.HFSecret.Name,
573-
"hfSecretKey": n.Spec.ModelDownloadJobs.HFSecret.Key,
574572
"securityContext": n.Spec.ModelDownloadJobs.SecurityContext,
575573
"ttlSecondsAfterFinished": n.Spec.ModelDownloadJobs.TTLSecondsAfterFinished,
576574
"pollIntervalSeconds": n.Spec.ModelDownloadJobs.PollIntervalSeconds,
577575
}
576+
577+
// add HF secret only if present
578+
if n.Spec.ModelDownloadJobs.HFSecret.Name != "" {
579+
if modelDownloadJobs, ok := cfg["model_download_jobs"].(map[string]interface{}); ok {
580+
modelDownloadJobs["hfSecretName"] = n.Spec.ModelDownloadJobs.HFSecret.Name
581+
modelDownloadJobs["hfSecretKey"] = n.Spec.ModelDownloadJobs.HFSecret.Key
582+
}
583+
}
584+
578585
return nil
579586
}
580587

internal/controller/nemocustomizer_controller_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,12 @@ var _ = Describe("NemoCustomizer Controller", func() {
109109
Expect(err).ToNot(HaveOccurred())
110110
trainingCM := loadConfigMapFromFile(filepath.Join(testDataDir, "training_config.yaml"))
111111
modelsCM := loadConfigMapFromFile(filepath.Join(testDataDir, "models_config.yaml"))
112+
modelTargetsCM := loadConfigMapFromFile(filepath.Join(testDataDir, "models_config_targets.yaml"))
112113

113114
// Register the test ConfigMaps in the cluster
114115
Expect(reconciler.GetClient().Create(ctx, trainingCM)).To(Succeed())
115116
Expect(reconciler.GetClient().Create(ctx, modelsCM)).To(Succeed())
117+
Expect(reconciler.GetClient().Create(ctx, modelTargetsCM)).To(Succeed())
116118

117119
nemoCustomizer = &appsv1alpha1.NemoCustomizer{
118120
ObjectMeta: metav1.ObjectMeta{
@@ -365,6 +367,13 @@ var _ = Describe("NemoCustomizer Controller", func() {
365367
if err := k8sClient.Get(ctx, modelsCMName, modelsCM); err == nil {
366368
Expect(k8sClient.Delete(ctx, modelsCM)).To(Succeed())
367369
}
370+
371+
// Delete the models targets config
372+
modelTargetsCMName := types.NamespacedName{Name: "nemo-model-target-config", Namespace: "default"}
373+
modelTargetsCM := &corev1.ConfigMap{}
374+
if err := k8sClient.Get(ctx, modelTargetsCMName, modelTargetsCM); err == nil {
375+
Expect(k8sClient.Delete(ctx, modelTargetsCM)).To(Succeed())
376+
}
368377
})
369378

370379
Describe("Reconcile", func() {
@@ -575,6 +584,74 @@ var _ = Describe("NemoCustomizer Controller", func() {
575584
Expect(parsed).To(HaveKeyWithValue("mlflow_tracking_url", "http://mlflow-tracking.nemo.svc.cluster.local:80"))
576585
})
577586

587+
It("should create customizer config with model targets and templates", func() {
588+
namespacedName := types.NamespacedName{Name: nemoCustomizer.Name, Namespace: "default"}
589+
590+
// use models config map with targets and templates
591+
nemoCustomizer.Spec.Models.Name = "nemo-model-config-targets"
592+
593+
err := client.Create(context.TODO(), nemoCustomizer)
594+
Expect(err).NotTo(HaveOccurred())
595+
err = client.Create(context.TODO(), secrets)
596+
Expect(err).NotTo(HaveOccurred())
597+
598+
result, err := reconciler.Reconcile(context.TODO(), reconcile.Request{NamespacedName: namespacedName})
599+
Expect(err).NotTo(HaveOccurred())
600+
Expect(result).To(Equal(ctrl.Result{}))
601+
602+
err = client.Get(ctx, namespacedName, nemoCustomizer)
603+
Expect(err).ToNot(HaveOccurred())
604+
Expect(nemoCustomizer.Finalizers).To(ContainElement(NemoCustomizerFinalizer))
605+
606+
// Check that the customizer config map was created
607+
configMap := &corev1.ConfigMap{}
608+
err = client.Get(context.TODO(), types.NamespacedName{
609+
Name: nemoCustomizer.Name,
610+
Namespace: nemoCustomizer.Namespace,
611+
}, configMap)
612+
Expect(err).NotTo(HaveOccurred())
613+
614+
// Verify metadata
615+
Expect(configMap.Name).To(Equal(nemoCustomizer.GetName()))
616+
Expect(configMap.Namespace).To(Equal(nemoCustomizer.Namespace))
617+
// Verify key exists
618+
Expect(configMap.Data).To(HaveKey("config.yaml"))
619+
configData := configMap.Data["config.yaml"]
620+
Expect(configData).NotTo(BeEmpty())
621+
622+
// Verify presence of top-level keys
623+
Expect(configData).To(ContainSubstring("training:"))
624+
Expect(configData).To(ContainSubstring("customizationTargets:"))
625+
Expect(configData).To(ContainSubstring("customizationConfigTemplates:"))
626+
Expect(configData).ToNot(ContainSubstring("models:")) // "models" is deprecated from NMR v25.06
627+
Expect(configData).To(ContainSubstring("model_download_jobs:"))
628+
629+
// Unmarshal the full merged config
630+
var parsed map[string]interface{}
631+
err = yaml.Unmarshal([]byte(configData), &parsed)
632+
Expect(err).NotTo(HaveOccurred())
633+
634+
// Validate model download jobs config with new secret params from NMR v25.06
635+
training, ok := parsed["model_download_jobs"].(map[string]interface{})
636+
Expect(ok).To(BeTrue(), "expected 'training' to be a map")
637+
Expect(training).To(HaveKey("ngcSecretName"))
638+
Expect(training).To(HaveKey("ngcSecretKey"))
639+
640+
// Validate model targets
641+
modelTargets, ok := parsed["customizationTargets"].(map[string]interface{})
642+
Expect(ok).To(BeTrue(), "expected 'modelTargets' to be a map")
643+
Expect(modelTargets).To(HaveKey("targets"))
644+
645+
// Validate model config templates
646+
configTemplates, ok := parsed["customizationConfigTemplates"].(map[string]interface{})
647+
Expect(ok).To(BeTrue(), "expected 'configTemplates' to be a map")
648+
Expect(configTemplates).To(HaveKey("templates"))
649+
650+
Expect(parsed).To(HaveKeyWithValue("entity_store_url", "http://nemoentitystore-sample.nemo.svc.cluster.local:8000"))
651+
Expect(parsed).To(HaveKeyWithValue("nemo_data_store_url", "http://nemodatastore-sample.nemo.svc.cluster.local:8000"))
652+
Expect(parsed).To(HaveKeyWithValue("mlflow_tracking_url", "http://mlflow-tracking.nemo.svc.cluster.local:80"))
653+
})
654+
578655
It("should delete HPA when NemoCustomizer is updated", func() {
579656
namespacedName := types.NamespacedName{Name: nemoCustomizer.Name, Namespace: "default"}
580657
err := client.Create(context.TODO(), nemoCustomizer)

0 commit comments

Comments
 (0)