@@ -1235,6 +1235,85 @@ func TestCreateSnapshotWithoutCompression(t *testing.T) {
12351235 _ = os .RemoveAll ("/tmp/snapshot-name-no-compress" )
12361236}
12371237
1238+ func TestCreateSnapshotWithDifferentShareInSnapshotClass (t * testing.T ) {
1239+ // Test that CreateSnapshot succeeds when VolumeSnapshotClass specifies
1240+ // a different server/share than the source volume. This verifies that
1241+ // the source volume mount uses server/share from the volumeHandle,
1242+ // not from the snapshot class parameters.
1243+ cs := initTestController (t )
1244+
1245+ // Setup: create source directory matching the source volume path
1246+ srcPath := "/tmp/src-pv-cross-share/subdir"
1247+ if err := os .MkdirAll (srcPath , 0777 ); err != nil {
1248+ t .Fatalf ("failed to create source directory: %v" , err )
1249+ }
1250+ defer func () { _ = os .RemoveAll ("/tmp/src-pv-cross-share" ) }()
1251+ defer func () { _ = os .RemoveAll ("/tmp/snapshot-cross-share" ) }()
1252+
1253+ // Snapshot class parameters specify a DIFFERENT server/share than the source volume.
1254+ // Note: share value omits leading '/' consistent with paramShare convention in this repo.
1255+ req := & csi.CreateSnapshotRequest {
1256+ SourceVolumeId : "nfs-server.default.svc.cluster.local#share#subdir#src-pv-cross-share" ,
1257+ Name : "snapshot-cross-share" ,
1258+ Parameters : map [string ]string {
1259+ paramServer : "other-nfs-server.default.svc.cluster.local" ,
1260+ paramShare : "different-share" ,
1261+ },
1262+ }
1263+
1264+ resp , err := cs .CreateSnapshot (context .TODO (), req )
1265+ if err != nil {
1266+ t .Fatalf ("CreateSnapshot failed with cross-share snapshot class: %v" , err )
1267+ }
1268+
1269+ if resp == nil || resp .Snapshot == nil {
1270+ t .Fatalf ("CreateSnapshot returned nil response" )
1271+ }
1272+
1273+ // Verify the snapshot was created successfully
1274+ expectedSourceVolumeID := "nfs-server.default.svc.cluster.local#share#subdir#src-pv-cross-share"
1275+ if resp .Snapshot .SourceVolumeId != expectedSourceVolumeID {
1276+ t .Errorf ("expected SourceVolumeId %q, got %q" , expectedSourceVolumeID , resp .Snapshot .SourceVolumeId )
1277+ }
1278+
1279+ // Verify that the FakeMounter was called with the correct mount sources:
1280+ // - source volume mount should use the source volume's server/share
1281+ // - snapshot volume mount should use the snapshot class's server/share
1282+ fakeMounter := cs .Driver .ns .mounter .(* mount.FakeMounter )
1283+ mountLog := fakeMounter .GetLog ()
1284+
1285+ var foundSourceMount , foundSnapMount bool
1286+ for _ , action := range mountLog {
1287+ if action .Action != "mount" {
1288+ continue
1289+ }
1290+ // Source volume mount: server from volumeHandle, share from volumeHandle
1291+ // Use filepath.ToSlash to normalize Windows backslash separators
1292+ normalizedSource := filepath .ToSlash (action .Source )
1293+ if normalizedSource == "nfs-server.default.svc.cluster.local:/share" {
1294+ foundSourceMount = true
1295+ }
1296+ // Snapshot destination mount: server/share from snapshot class parameters
1297+ if normalizedSource == "other-nfs-server.default.svc.cluster.local:/different-share" {
1298+ foundSnapMount = true
1299+ }
1300+ }
1301+ if ! foundSourceMount {
1302+ t .Errorf ("expected source volume mount with source %q, mount log: %+v" ,
1303+ "nfs-server.default.svc.cluster.local:/share" , mountLog )
1304+ }
1305+ if ! foundSnapMount {
1306+ t .Errorf ("expected snapshot destination mount with source %q, mount log: %+v" ,
1307+ "other-nfs-server.default.svc.cluster.local:/different-share" , mountLog )
1308+ }
1309+
1310+ // Verify the snapshot archive file was created
1311+ archivePath := "/tmp/snapshot-cross-share/snapshot-cross-share/src-pv-cross-share.tar.gz"
1312+ if _ , err := os .Stat (archivePath ); os .IsNotExist (err ) {
1313+ t .Errorf ("expected snapshot archive at %s, but it does not exist" , archivePath )
1314+ }
1315+ }
1316+
12381317func TestCopyVolumeFromUncompressedSnapshot (t * testing.T ) {
12391318 // Create an uncompressed snapshot archive and test restoration
12401319 srcPath := "/tmp/uncompressed-snapshot-test/uncompressed-snapshot-test"
0 commit comments