@@ -853,6 +853,21 @@ func TestFirecracker_RemoteSnapshotSharing(t *testing.T) {
853
853
}
854
854
})
855
855
856
+ workDir := testfs .MakeDirAll (t , rootDir , "work" )
857
+ opts := firecracker.ContainerOpts {
858
+ ContainerImage : busyboxImage ,
859
+ ActionWorkingDirectory : workDir ,
860
+ VMConfiguration : & fcpb.VMConfiguration {
861
+ NumCpus : 1 ,
862
+ MemSizeMb : minMemSizeMB , // small to make snapshotting faster.
863
+ EnableNetworking : false ,
864
+ ScratchDiskSizeMb : 100 ,
865
+ GuestKernelVersion : cfg .GuestKernelVersion ,
866
+ FirecrackerVersion : cfg .FirecrackerVersion ,
867
+ GuestApiVersion : cfg .GuestAPIVersion ,
868
+ },
869
+ ExecutorConfig : cfg ,
870
+ }
856
871
instanceName := "test-instance-name"
857
872
task := & repb.ExecutionTask {
858
873
Command : & repb.Command {
@@ -861,62 +876,57 @@ func TestFirecracker_RemoteSnapshotSharing(t *testing.T) {
861
876
{Name : "recycle-runner" , Value : "true" },
862
877
}},
863
878
Arguments : []string {"./buildbuddy_ci_runner" },
864
- // Simulate that this is for a PR branch, because master snapshots
865
- // are always saved to the remote cache.
866
- EnvironmentVariables : []* repb.Command_EnvironmentVariable {
867
- {Name : "GIT_REPO_DEFAULT_BRANCH" , Value : "master" },
868
- {Name : "GIT_BRANCH" , Value : "my-pr" },
869
- },
870
879
},
871
880
ExecuteRequest : & repb.ExecuteRequest {
872
881
InstanceName : instanceName ,
873
882
},
874
883
}
884
+ baseVM , err := firecracker .NewContainer (ctx , env , task , opts )
885
+ require .NoError (t , err )
886
+ containersToCleanup = append (containersToCleanup , baseVM )
887
+ err = container .PullImageIfNecessary (ctx , env , baseVM , oci.Credentials {}, opts .ContainerImage )
888
+ require .NoError (t , err )
889
+ err = baseVM .Create (ctx , opts .ActionWorkingDirectory )
890
+ require .NoError (t , err )
891
+ baseSnapshotId := baseVM .SnapshotID ()
875
892
876
- runAndSnapshotVM := func (workDir string , stringToLog string , expectedOutput string , snapshotKeyOverride * fcpb.SnapshotKey ) string {
877
- opts := firecracker.ContainerOpts {
878
- ContainerImage : busyboxImage ,
879
- ActionWorkingDirectory : workDir ,
880
- VMConfiguration : & fcpb.VMConfiguration {
881
- NumCpus : 1 ,
882
- MemSizeMb : minMemSizeMB , // small to make snapshotting faster.
883
- EnableNetworking : false ,
884
- ScratchDiskSizeMb : 100 ,
885
- },
886
- ExecutorConfig : cfg ,
887
- OverrideSnapshotKey : snapshotKeyOverride ,
888
- }
889
- vm , err := firecracker .NewContainer (ctx , env , task , opts )
890
- require .NoError (t , err )
891
- containersToCleanup = append (containersToCleanup , vm )
892
- err = vm .Create (ctx , workDir )
893
- require .NoError (t , err )
894
- cmd := appendToLog (stringToLog )
895
- res := vm .Exec (ctx , cmd , nil /*=stdio*/ )
896
- require .NoError (t , res .Error )
897
- require .Equal (t , expectedOutput , string (res .Stdout ))
898
- require .NotEmpty (t , res .VMMetadata .GetSnapshotId ())
899
- err = vm .Pause (ctx )
900
- require .NoError (t , err )
893
+ // Create a snapshot. Data written to this snapshot should persist
894
+ // when other VMs reuse the snapshot
895
+ cmd := appendToLog ("Base" )
896
+ res := baseVM .Exec (ctx , cmd , nil /*=stdio*/ )
897
+ require .NoError (t , res .Error )
898
+ require .Equal (t , "Base\n " , string (res .Stdout ))
899
+ require .NotEmpty (t , res .VMMetadata .GetSnapshotId ())
900
+ err = baseVM .Pause (ctx )
901
+ require .NoError (t , err )
901
902
902
- return vm .SnapshotID ()
903
+ // Start a VM from the snapshot. Artifacts should be stored locally in the filecache
904
+ workDirForkLocalFetch := testfs .MakeDirAll (t , rootDir , "work-fork-local-fetch" )
905
+ opts = firecracker.ContainerOpts {
906
+ ContainerImage : busyboxImage ,
907
+ ActionWorkingDirectory : workDirForkLocalFetch ,
908
+ VMConfiguration : & fcpb.VMConfiguration {
909
+ NumCpus : 1 ,
910
+ MemSizeMb : minMemSizeMB , // small to make snapshotting faster.
911
+ EnableNetworking : false ,
912
+ ScratchDiskSizeMb : 100 ,
913
+ },
914
+ ExecutorConfig : cfg ,
903
915
}
904
-
905
- // Create a snapshot. Data written to this snapshot should be cached remotely,
906
- // and persist when other VMs reuse the snapshot.
907
- workDir := testfs .MakeDirAll (t , rootDir , "work" )
908
- baseSnapshotId := runAndSnapshotVM (workDir , "Cache Remotely" , "Cache Remotely\n " , nil )
909
-
910
- // Start a VM from the snapshot. Artifacts should be stored locally in the filecache.
916
+ forkedVM , err := firecracker .NewContainer (ctx , env , task , opts )
917
+ require .NoError (t , err )
918
+ containersToCleanup = append (containersToCleanup , forkedVM )
919
+ err = forkedVM .Unpause (ctx )
920
+ require .NoError (t , err )
921
+ cmd = appendToLog ("Fork local fetch" )
922
+ res = forkedVM .Exec (ctx , cmd , nil /*=stdio*/ )
923
+ require .NoError (t , res .Error )
911
924
// The log should contain data written to the original snapshot
912
- // and the current VM.
913
- workDirForkLocalFetch := testfs .MakeDirAll (t , rootDir , "work-fork-local-fetch" )
914
- runAndSnapshotVM (workDirForkLocalFetch , "Cache Locally" , "Cache Remotely\n Cache Locally\n " , nil )
915
-
916
- // Start another VM from the locally cached snapshot. The log should contain
917
- // data from the most recent run, as well as the current run.
918
- workDirForkLocalFetch2 := testfs .MakeDirAll (t , rootDir , "work-fork-local-fetch" )
919
- runAndSnapshotVM (workDirForkLocalFetch2 , "Cache Locally 2" , "Cache Remotely\n Cache Locally\n Cache Locally 2\n " , nil )
925
+ // and the current VM
926
+ require .Equal (t , "Base\n Fork local fetch\n " , string (res .Stdout ))
927
+ require .NotEmpty (t , res .VMMetadata .GetSnapshotId ())
928
+ err = forkedVM .Pause (ctx )
929
+ require .NoError (t , err )
920
930
921
931
// Clear the local filecache. Vms should still be able to unpause the snapshot
922
932
// by pulling artifacts from the remote cache
@@ -928,25 +938,65 @@ func TestFirecracker_RemoteSnapshotSharing(t *testing.T) {
928
938
fc2 .WaitForDirectoryScanToComplete ()
929
939
env .SetFileCache (fc2 )
930
940
931
- // Start a VM from the remote snapshot. The log should contain data from the
932
- // first run, which was saved remotely, but not the two most recent runs which
933
- // were only cached locally.
941
+ // Start a VM from the snapshot.
934
942
workDirForkRemoteFetch := testfs .MakeDirAll (t , rootDir , "work-fork-remote-fetch" )
935
- runAndSnapshotVM (workDirForkRemoteFetch , "Cache Locally 3" , "Cache Remotely\n Cache Locally 3\n " , nil )
943
+ opts = firecracker.ContainerOpts {
944
+ ContainerImage : busyboxImage ,
945
+ ActionWorkingDirectory : workDirForkRemoteFetch ,
946
+ VMConfiguration : & fcpb.VMConfiguration {
947
+ NumCpus : 1 ,
948
+ MemSizeMb : minMemSizeMB , // small to make snapshotting faster.
949
+ EnableNetworking : false ,
950
+ ScratchDiskSizeMb : 100 ,
951
+ },
952
+ ExecutorConfig : cfg ,
953
+ }
954
+ forkedVM2 , err := firecracker .NewContainer (ctx , env , task , opts )
955
+ require .NoError (t , err )
956
+ containersToCleanup = append (containersToCleanup , forkedVM2 )
957
+ err = forkedVM2 .Unpause (ctx )
958
+ require .NoError (t , err )
959
+ cmd = appendToLog ("Fork remote fetch" )
960
+ res = forkedVM2 .Exec (ctx , cmd , nil /*=stdio*/ )
961
+ require .NoError (t , res .Error )
962
+ // The log should contain data written to the most recent snapshot
963
+ require .Equal (t , "Base\n Fork local fetch\n Fork remote fetch\n " , string (res .Stdout ))
964
+ require .NotEmpty (t , res .VMMetadata .GetSnapshotId ())
936
965
937
966
// Should still be able to start from the original snapshot if we use
938
967
// a snapshot key containing the original VM's snapshot ID.
939
968
// Note that when using a snapshot ID as the key, we only include the
940
969
// snapshot_id and instance_name fields.
941
- // The log should contain data written to the original snapshot
942
- // and the current VM, but not from any of the other VMs, including the master
943
- // snapshot
944
970
workDirForkOriginalSnapshot := testfs .MakeDirAll (t , rootDir , "work-fork-og-snapshot" )
945
971
originalSnapshotKey := & fcpb.SnapshotKey {
946
972
InstanceName : instanceName ,
947
973
SnapshotId : baseSnapshotId ,
948
974
}
949
- runAndSnapshotVM (workDirForkOriginalSnapshot , "Fork from original vm" , "Cache Remotely\n Fork from original vm\n " , originalSnapshotKey )
975
+ opts = firecracker.ContainerOpts {
976
+ ContainerImage : busyboxImage ,
977
+ ActionWorkingDirectory : workDirForkOriginalSnapshot ,
978
+ VMConfiguration : & fcpb.VMConfiguration {
979
+ NumCpus : 1 ,
980
+ MemSizeMb : minMemSizeMB , // small to make snapshotting faster.
981
+ EnableNetworking : false ,
982
+ ScratchDiskSizeMb : 100 ,
983
+ },
984
+ ExecutorConfig : cfg ,
985
+ OverrideSnapshotKey : originalSnapshotKey ,
986
+ }
987
+ ogFork , err := firecracker .NewContainer (ctx , env , task , opts )
988
+ require .NoError (t , err )
989
+ containersToCleanup = append (containersToCleanup , ogFork )
990
+ err = ogFork .Unpause (ctx )
991
+ require .NoError (t , err )
992
+ cmd = appendToLog ("Fork from original vm" )
993
+ res = ogFork .Exec (ctx , cmd , nil /*=stdio*/ )
994
+ require .NoError (t , res .Error )
995
+ // The log should contain data written to the original snapshot
996
+ // and the current VM, but not from any of the other VMs, including the master
997
+ // snapshot
998
+ require .Equal (t , "Base\n Fork from original vm\n " , string (res .Stdout ))
999
+ require .NotEmpty (t , res .VMMetadata .GetSnapshotId ())
950
1000
}
951
1001
952
1002
func TestFirecracker_RemoteSnapshotSharing_RemoteInstanceName (t * testing.T ) {
0 commit comments