@@ -3493,6 +3493,133 @@ def test_delete_custom_config(self):
3493
3493
except Exception as ex :
3494
3494
self .assertTrue (False , "unexpected error {}" .format (ex ))
3495
3495
3496
+ def test_load_new_model_version (self ):
3497
+ model_name = "identity_fp32"
3498
+ client = self ._get_client (use_grpc = True )
3499
+
3500
+ # version 1 and 2 are already loaded
3501
+ # version 3 is in the model directory but not loaded
3502
+ # version 4 does not exist anywhere
3503
+ self .assertTrue (client .is_model_ready (model_name , "1" ))
3504
+ self .assertTrue (client .is_model_ready (model_name , "2" ))
3505
+ self .assertFalse (client .is_model_ready (model_name , "3" ))
3506
+ self .assertFalse (client .is_model_ready (model_name , "4" ))
3507
+ with open (os .environ ["SERVER_LOG" ]) as f :
3508
+ server_log = f .read ()
3509
+ self .assertEqual (server_log .count ("[PB model] Loading version 1" ), 1 )
3510
+ self .assertEqual (server_log .count ("[PB model] Loading version 2" ), 1 )
3511
+ self .assertEqual (server_log .count ("[PB model] Loading version 3" ), 0 )
3512
+ self .assertEqual (server_log .count ("[PB model] Loading version 4" ), 0 )
3513
+ self .assertEqual (server_log .count ("successfully loaded 'identity_fp32'" ), 1 )
3514
+
3515
+ # update version 2 model file
3516
+ Path (os .path .join ("models" , model_name , "2" , "model.py" )).touch ()
3517
+ # add version 4 model file
3518
+ src_path = os .path .join ("models" , model_name , "3" )
3519
+ dst_path = os .path .join ("models" , model_name , "4" )
3520
+ shutil .copytree (src_path , dst_path )
3521
+ # update model config to load version 1 to 4
3522
+ config_path = os .path .join ("models" , model_name , "config.pbtxt" )
3523
+ with open (config_path , mode = "r+" , encoding = "utf-8" , errors = "strict" ) as f :
3524
+ config = f .read ()
3525
+ config = config .replace (
3526
+ "version_policy: { specific: { versions: [1, 2] } }" ,
3527
+ "version_policy: { specific: { versions: [1, 2, 3, 4] } }" ,
3528
+ )
3529
+ f .truncate (0 )
3530
+ f .seek (0 )
3531
+ f .write (config )
3532
+ # reload the model
3533
+ client .load_model (model_name )
3534
+
3535
+ # version 1 is unmodified so it should not be reloaded
3536
+ # version 2 is modified so it should be reloaded
3537
+ # version 3 model file existed but not loaded so it should be loaded
3538
+ # version 4 is a new version so it should be loaded
3539
+ self .assertTrue (client .is_model_ready (model_name , "1" ))
3540
+ self .assertTrue (client .is_model_ready (model_name , "2" ))
3541
+ self .assertTrue (client .is_model_ready (model_name , "3" ))
3542
+ self .assertTrue (client .is_model_ready (model_name , "4" ))
3543
+ with open (os .environ ["SERVER_LOG" ]) as f :
3544
+ server_log = f .read ()
3545
+ self .assertEqual (server_log .count ("[PB model] Loading version 1" ), 1 )
3546
+ self .assertEqual (server_log .count ("[PB model] Loading version 2" ), 2 )
3547
+ self .assertEqual (server_log .count ("[PB model] Loading version 3" ), 1 )
3548
+ self .assertEqual (server_log .count ("[PB model] Loading version 4" ), 1 )
3549
+ self .assertEqual (server_log .count ("successfully loaded 'identity_fp32'" ), 2 )
3550
+
3551
+ # simulate a dependency change to all versions
3552
+ Path (os .path .join ("models" , model_name , "dummy_dependency.py" )).touch ()
3553
+ # reload the model
3554
+ client .load_model (model_name )
3555
+
3556
+ # all 4 versions should be reloaded
3557
+ self .assertTrue (client .is_model_ready (model_name , "1" ))
3558
+ self .assertTrue (client .is_model_ready (model_name , "2" ))
3559
+ self .assertTrue (client .is_model_ready (model_name , "3" ))
3560
+ self .assertTrue (client .is_model_ready (model_name , "4" ))
3561
+ with open (os .environ ["SERVER_LOG" ]) as f :
3562
+ server_log = f .read ()
3563
+ self .assertEqual (server_log .count ("[PB model] Loading version 1" ), 2 )
3564
+ self .assertEqual (server_log .count ("[PB model] Loading version 2" ), 3 )
3565
+ self .assertEqual (server_log .count ("[PB model] Loading version 3" ), 2 )
3566
+ self .assertEqual (server_log .count ("[PB model] Loading version 4" ), 2 )
3567
+ self .assertEqual (server_log .count ("successfully loaded 'identity_fp32'" ), 3 )
3568
+
3569
+ # update model config to only load version 4
3570
+ config_path = os .path .join ("models" , model_name , "config.pbtxt" )
3571
+ with open (config_path , mode = "r+" , encoding = "utf-8" , errors = "strict" ) as f :
3572
+ config = f .read ()
3573
+ config = config .replace (
3574
+ "version_policy: { specific: { versions: [1, 2, 3, 4] } }" ,
3575
+ "version_policy: { specific: { versions: [4] } }" ,
3576
+ )
3577
+ f .truncate (0 )
3578
+ f .seek (0 )
3579
+ f .write (config )
3580
+ # reload the model
3581
+ client .load_model (model_name )
3582
+
3583
+ # only version 4 should be available and no reloads should happen
3584
+ self .assertFalse (client .is_model_ready (model_name , "1" ))
3585
+ self .assertFalse (client .is_model_ready (model_name , "2" ))
3586
+ self .assertFalse (client .is_model_ready (model_name , "3" ))
3587
+ self .assertTrue (client .is_model_ready (model_name , "4" ))
3588
+ with open (os .environ ["SERVER_LOG" ]) as f :
3589
+ server_log = f .read ()
3590
+ self .assertEqual (server_log .count ("[PB model] Loading version 1" ), 2 )
3591
+ self .assertEqual (server_log .count ("[PB model] Loading version 2" ), 3 )
3592
+ self .assertEqual (server_log .count ("[PB model] Loading version 3" ), 2 )
3593
+ self .assertEqual (server_log .count ("[PB model] Loading version 4" ), 2 )
3594
+ self .assertEqual (server_log .count ("successfully loaded 'identity_fp32'" ), 4 )
3595
+
3596
+ # update model config to load version 1 and 4
3597
+ config_path = os .path .join ("models" , model_name , "config.pbtxt" )
3598
+ with open (config_path , mode = "r+" , encoding = "utf-8" , errors = "strict" ) as f :
3599
+ config = f .read ()
3600
+ config = config .replace (
3601
+ "version_policy: { specific: { versions: [4] } }" ,
3602
+ "version_policy: { specific: { versions: [1, 4] } }" ,
3603
+ )
3604
+ f .truncate (0 )
3605
+ f .seek (0 )
3606
+ f .write (config )
3607
+ # reload the model
3608
+ client .load_model (model_name )
3609
+
3610
+ # version 1 should be loaded and version 4 should not be reloaded
3611
+ self .assertTrue (client .is_model_ready (model_name , "1" ))
3612
+ self .assertFalse (client .is_model_ready (model_name , "2" ))
3613
+ self .assertFalse (client .is_model_ready (model_name , "3" ))
3614
+ self .assertTrue (client .is_model_ready (model_name , "4" ))
3615
+ with open (os .environ ["SERVER_LOG" ]) as f :
3616
+ server_log = f .read ()
3617
+ self .assertEqual (server_log .count ("[PB model] Loading version 1" ), 3 )
3618
+ self .assertEqual (server_log .count ("[PB model] Loading version 2" ), 3 )
3619
+ self .assertEqual (server_log .count ("[PB model] Loading version 3" ), 2 )
3620
+ self .assertEqual (server_log .count ("[PB model] Loading version 4" ), 2 )
3621
+ self .assertEqual (server_log .count ("successfully loaded 'identity_fp32'" ), 5 )
3622
+
3496
3623
3497
3624
if __name__ == "__main__" :
3498
3625
unittest .main ()
0 commit comments