@@ -14,14 +14,15 @@ import (
1414
1515// MockGPUCreateStore is a mock implementation of GPUCreateStore for testing
1616type MockGPUCreateStore struct {
17- User * entity.User
18- Org * entity.Organization
19- Workspaces map [string ]* entity.Workspace
20- CreateError error
21- CreateErrorTypes map [string ]error // Errors for specific instance types
22- DeleteError error
23- CreatedWorkspaces []* entity.Workspace
24- DeletedWorkspaceIDs []string
17+ User * entity.User
18+ Org * entity.Organization
19+ Workspaces map [string ]* entity.Workspace
20+ CreateError error
21+ CreateErrorTypes map [string ]error // Errors for specific instance types
22+ DeleteError error
23+ CreatedWorkspaces []* entity.Workspace
24+ DeletedWorkspaceIDs []string
25+ FetchedLifeCycleScriptIDs []string
2526}
2627
2728func NewMockGPUCreateStore () * MockGPUCreateStore {
@@ -110,6 +111,13 @@ func (m *MockGPUCreateStore) GetLaunchable(launchableID string) (*store.Launchab
110111 }, nil
111112}
112113
114+ func (m * MockGPUCreateStore ) GetLaunchableLifeCycleScript (launchableID , scriptID string ) (* store.LifeCycleScriptResponse , error ) {
115+ m .FetchedLifeCycleScriptIDs = append (m .FetchedLifeCycleScriptIDs , scriptID )
116+ return & store.LifeCycleScriptResponse {
117+ Attrs : & store.LifeCycleScriptAttr {ID : scriptID , Script : "echo mock-script" },
118+ }, nil
119+ }
120+
113121func (m * MockGPUCreateStore ) RedeemCouponCode (organizationID string , code string ) (* store.RedeemCouponCodeResponse , error ) {
114122 return & store.RedeemCouponCodeResponse {}, nil
115123}
@@ -665,3 +673,77 @@ func TestPollUntilReadyReportsWorkspaceFailureMessage(t *testing.T) {
665673
666674 assert .ErrorContains (t , err , "instance test failed: unexpected end of JSON input" )
667675}
676+
677+ func TestInlineLaunchableLifeCycleScript (t * testing.T ) {
678+ t .Run ("fetches and inlines lifecycle script body" , func (t * testing.T ) {
679+ mockStore := NewMockGPUCreateStore ()
680+ info := & store.LaunchableResponse {
681+ BuildRequest : store.LaunchableBuildRequest {
682+ VMBuild : & store.VMBuild {
683+ LifeCycleScriptAttr : & store.LifeCycleScriptAttr {ID : "ls-abc" },
684+ },
685+ },
686+ }
687+
688+ err := inlineLaunchableLifeCycleScript (mockStore , "env-abc" , info )
689+
690+ assert .NoError (t , err )
691+ assert .Equal (t , []string {"ls-abc" }, mockStore .FetchedLifeCycleScriptIDs )
692+ assert .Equal (t , "echo mock-script" , info .BuildRequest .VMBuild .LifeCycleScriptAttr .Script )
693+ })
694+
695+ t .Run ("skips fetch when info is nil" , func (t * testing.T ) {
696+ mockStore := NewMockGPUCreateStore ()
697+
698+ err := inlineLaunchableLifeCycleScript (mockStore , "env-abc" , nil )
699+
700+ assert .NoError (t , err )
701+ assert .Empty (t , mockStore .FetchedLifeCycleScriptIDs )
702+ })
703+
704+ t .Run ("container build skips lifecycle script fetch" , func (t * testing.T ) {
705+ mockStore := NewMockGPUCreateStore ()
706+ info := & store.LaunchableResponse {
707+ BuildRequest : store.LaunchableBuildRequest {
708+ CustomContainer : & store.CustomContainer {ContainerURL : "nvcr.io/nvidia/test:latest" },
709+ },
710+ }
711+
712+ err := inlineLaunchableLifeCycleScript (mockStore , "env-abc" , info )
713+
714+ assert .NoError (t , err )
715+ assert .Empty (t , mockStore .FetchedLifeCycleScriptIDs )
716+ })
717+
718+ t .Run ("skips fetch when launchable has no lifecycle script" , func (t * testing.T ) {
719+ mockStore := NewMockGPUCreateStore ()
720+ info := & store.LaunchableResponse {
721+ BuildRequest : store.LaunchableBuildRequest {
722+ VMBuild : & store.VMBuild {ForceJupyterInstall : true },
723+ },
724+ }
725+
726+ err := inlineLaunchableLifeCycleScript (mockStore , "env-abc" , info )
727+
728+ assert .NoError (t , err )
729+ assert .Empty (t , mockStore .FetchedLifeCycleScriptIDs )
730+ assert .Nil (t , info .BuildRequest .VMBuild .LifeCycleScriptAttr )
731+ })
732+
733+ t .Run ("skips fetch when script ID is empty" , func (t * testing.T ) {
734+ mockStore := NewMockGPUCreateStore ()
735+ info := & store.LaunchableResponse {
736+ BuildRequest : store.LaunchableBuildRequest {
737+ VMBuild : & store.VMBuild {
738+ LifeCycleScriptAttr : & store.LifeCycleScriptAttr {Name : "stale" },
739+ },
740+ },
741+ }
742+
743+ err := inlineLaunchableLifeCycleScript (mockStore , "env-abc" , info )
744+
745+ assert .NoError (t , err )
746+ assert .Empty (t , mockStore .FetchedLifeCycleScriptIDs )
747+ assert .Equal (t , "" , info .BuildRequest .VMBuild .LifeCycleScriptAttr .Script )
748+ })
749+ }
0 commit comments