@@ -1431,3 +1431,184 @@ func TestGenerateDownloadOverrideTaskBasedOnBaseModel_TensorRTLLMAndMetadataType
14311431 assert .Equal (t , "a10" , filter .ShapeAlias )
14321432 assert .Equal (t , "CustomType" , filter .ModelType )
14331433}
1434+
1435+ func TestUpdateBaseModel_NoDuplicateTaskOnPolicyOnlyChange (t * testing.T ) {
1436+ logger , _ := zap .NewDevelopment ()
1437+ sugaredLogger := logger .Sugar ()
1438+ defer func (s * zap.SugaredLogger ) { _ = s .Sync () }(sugaredLogger )
1439+
1440+ ch := make (chan * GopherTask , 10 )
1441+ scout := & Scout {
1442+ nodeShapeAlias : "a10" ,
1443+ gopherChan : ch ,
1444+ logger : sugaredLogger ,
1445+ nodeInfo : & corev1.Node {
1446+ ObjectMeta : metav1.ObjectMeta {
1447+ Name : "test-node" ,
1448+ Labels : map [string ]string {"gpu-model" : "a10" },
1449+ },
1450+ },
1451+ }
1452+
1453+ tests := []struct {
1454+ name string
1455+ oldModel * v1beta1.BaseModel
1456+ newModel * v1beta1.BaseModel
1457+ expectedTasks int
1458+ description string
1459+ }{
1460+ {
1461+ name : "policy-only change on HuggingFace - exactly 1 task from dedicated handler" ,
1462+ oldModel : newBaseModel ("model-1" , v1beta1 .ReuseIfExists , "hf://meta-llama/llama-3" ),
1463+ newModel : newBaseModel ("model-1" , v1beta1 .AlwaysDownload , "hf://meta-llama/llama-3" ),
1464+ expectedTasks : 1 ,
1465+ description : "Only the dedicated policy-change handler should fire" ,
1466+ },
1467+ {
1468+ name : "policy-only change on non-HuggingFace - 0 tasks" ,
1469+ oldModel : newBaseModel ("model-2" , v1beta1 .ReuseIfExists , "oci://bucket/model" ),
1470+ newModel : newBaseModel ("model-2" , v1beta1 .AlwaysDownload , "oci://bucket/model" ),
1471+ expectedTasks : 0 ,
1472+ description : "Dedicated handler skips non-HF, spec diff excludes DownloadPolicy" ,
1473+ },
1474+ {
1475+ name : "non-policy spec change - exactly 1 task from hasChanges block" ,
1476+ oldModel : & v1beta1.BaseModel {
1477+ ObjectMeta : metav1.ObjectMeta {Name : "model-3" },
1478+ Spec : v1beta1.BaseModelSpec {
1479+ ModelExtensionSpec : v1beta1.ModelExtensionSpec {DisplayName : ptr ("Old Name" )},
1480+ Storage : & v1beta1.StorageSpec {
1481+ DownloadPolicy : ptr (v1beta1 .AlwaysDownload ),
1482+ StorageUri : ptr ("hf://meta-llama/llama-3" ),
1483+ },
1484+ },
1485+ },
1486+ newModel : & v1beta1.BaseModel {
1487+ ObjectMeta : metav1.ObjectMeta {Name : "model-3" },
1488+ Spec : v1beta1.BaseModelSpec {
1489+ ModelExtensionSpec : v1beta1.ModelExtensionSpec {DisplayName : ptr ("New Name" )},
1490+ Storage : & v1beta1.StorageSpec {
1491+ DownloadPolicy : ptr (v1beta1 .AlwaysDownload ),
1492+ StorageUri : ptr ("hf://meta-llama/llama-3" ),
1493+ },
1494+ },
1495+ },
1496+ expectedTasks : 1 ,
1497+ description : "Only the hasChanges block should fire" ,
1498+ },
1499+ {
1500+ name : "policy change + other spec change on HuggingFace - exactly 1 task" ,
1501+ oldModel : & v1beta1.BaseModel {
1502+ ObjectMeta : metav1.ObjectMeta {Name : "model-4" },
1503+ Spec : v1beta1.BaseModelSpec {
1504+ ModelExtensionSpec : v1beta1.ModelExtensionSpec {DisplayName : ptr ("Old Name" )},
1505+ Storage : & v1beta1.StorageSpec {
1506+ DownloadPolicy : ptr (v1beta1 .ReuseIfExists ),
1507+ StorageUri : ptr ("hf://meta-llama/llama-3" ),
1508+ },
1509+ },
1510+ },
1511+ newModel : & v1beta1.BaseModel {
1512+ ObjectMeta : metav1.ObjectMeta {Name : "model-4" },
1513+ Spec : v1beta1.BaseModelSpec {
1514+ ModelExtensionSpec : v1beta1.ModelExtensionSpec {DisplayName : ptr ("New Name" )},
1515+ Storage : & v1beta1.StorageSpec {
1516+ DownloadPolicy : ptr (v1beta1 .AlwaysDownload ),
1517+ StorageUri : ptr ("hf://meta-llama/llama-3" ),
1518+ },
1519+ },
1520+ },
1521+ expectedTasks : 1 ,
1522+ description : "Single task even when both policy and spec change" ,
1523+ },
1524+ }
1525+
1526+ for _ , tc := range tests {
1527+ t .Run (tc .name , func (t * testing.T ) {
1528+ scout .updateBaseModel (tc .oldModel , tc .newModel )
1529+ assert .Equal (t , tc .expectedTasks , len (ch ), tc .description )
1530+ for range tc .expectedTasks {
1531+ task := <- ch
1532+ assert .Equal (t , DownloadOverride , task .TaskType )
1533+ }
1534+ })
1535+ }
1536+ }
1537+
1538+ func TestUpdateClusterBaseModel_NoDuplicateTaskOnPolicyOnlyChange (t * testing.T ) {
1539+ logger , _ := zap .NewDevelopment ()
1540+ sugaredLogger := logger .Sugar ()
1541+ defer func (s * zap.SugaredLogger ) { _ = s .Sync () }(sugaredLogger )
1542+
1543+ ch := make (chan * GopherTask , 10 )
1544+ scout := & Scout {
1545+ nodeShapeAlias : "a10" ,
1546+ gopherChan : ch ,
1547+ logger : sugaredLogger ,
1548+ nodeInfo : & corev1.Node {
1549+ ObjectMeta : metav1.ObjectMeta {
1550+ Name : "test-node" ,
1551+ Labels : map [string ]string {"gpu-model" : "a10" },
1552+ },
1553+ },
1554+ }
1555+
1556+ tests := []struct {
1557+ name string
1558+ oldModel * v1beta1.ClusterBaseModel
1559+ newModel * v1beta1.ClusterBaseModel
1560+ expectedTasks int
1561+ description string
1562+ }{
1563+ {
1564+ name : "policy-only change on HuggingFace - exactly 1 task" ,
1565+ oldModel : newClusterBaseModel ("cbm-1" , v1beta1 .ReuseIfExists , "hf://meta-llama/llama-3" ),
1566+ newModel : newClusterBaseModel ("cbm-1" , v1beta1 .AlwaysDownload , "hf://meta-llama/llama-3" ),
1567+ expectedTasks : 1 ,
1568+ description : "Only the dedicated policy-change handler should fire" ,
1569+ },
1570+ {
1571+ name : "policy-only change on non-HuggingFace - 0 tasks" ,
1572+ oldModel : newClusterBaseModel ("cbm-2" , v1beta1 .ReuseIfExists , "oci://bucket/model" ),
1573+ newModel : newClusterBaseModel ("cbm-2" , v1beta1 .AlwaysDownload , "oci://bucket/model" ),
1574+ expectedTasks : 0 ,
1575+ description : "Dedicated handler skips non-HF, spec diff excludes DownloadPolicy" ,
1576+ },
1577+ {
1578+ name : "non-policy spec change - exactly 1 task" ,
1579+ oldModel : & v1beta1.ClusterBaseModel {
1580+ ObjectMeta : metav1.ObjectMeta {Name : "cbm-3" },
1581+ Spec : v1beta1.BaseModelSpec {
1582+ ModelExtensionSpec : v1beta1.ModelExtensionSpec {DisplayName : ptr ("Old Name" )},
1583+ Storage : & v1beta1.StorageSpec {
1584+ DownloadPolicy : ptr (v1beta1 .AlwaysDownload ),
1585+ StorageUri : ptr ("hf://meta-llama/llama-3" ),
1586+ },
1587+ },
1588+ },
1589+ newModel : & v1beta1.ClusterBaseModel {
1590+ ObjectMeta : metav1.ObjectMeta {Name : "cbm-3" },
1591+ Spec : v1beta1.BaseModelSpec {
1592+ ModelExtensionSpec : v1beta1.ModelExtensionSpec {DisplayName : ptr ("New Name" )},
1593+ Storage : & v1beta1.StorageSpec {
1594+ DownloadPolicy : ptr (v1beta1 .AlwaysDownload ),
1595+ StorageUri : ptr ("hf://meta-llama/llama-3" ),
1596+ },
1597+ },
1598+ },
1599+ expectedTasks : 1 ,
1600+ description : "Only the hasChanges block should fire" ,
1601+ },
1602+ }
1603+
1604+ for _ , tc := range tests {
1605+ t .Run (tc .name , func (t * testing.T ) {
1606+ scout .updateClusterBaseModel (tc .oldModel , tc .newModel )
1607+ assert .Equal (t , tc .expectedTasks , len (ch ), tc .description )
1608+ for range tc .expectedTasks {
1609+ task := <- ch
1610+ assert .Equal (t , DownloadOverride , task .TaskType )
1611+ }
1612+ })
1613+ }
1614+ }
0 commit comments