@@ -200,6 +200,73 @@ func Test_blobDownload_actualBlob(t *testing.T) {
200200 require .EqualValues (t , chunk , b , "retrieved body is different body=%d chunk=%d" , len (b ), len (chunk ))
201201}
202202
203+ func Test_GetSASBlob_nestedDirectories_actualBlob (t * testing.T ) {
204+ acct := os .Getenv ("AZURE_STORAGE_ACCOUNT" )
205+ key := os .Getenv ("AZURE_STORAGE_ACCESS_KEY" )
206+ if acct == "" || key == "" {
207+ t .Skipf ("Skipping: AZURE_STORAGE_ACCOUNT or AZURE_STORAGE_ACCESS_KEY not specified to run this test" )
208+ }
209+ base := storage .DefaultBaseURL
210+
211+ // Create a blob in a nested directory structure
212+ client , err := storage .NewClient (acct , key , base , storage .DefaultAPIVersion , true )
213+ require .Nil (t , err )
214+ blobStorageClient := client .GetBlobService ()
215+
216+ var (
217+ content = []byte ("test script content\n " )
218+ name = "dir1/dir2/script.sh" // nested path
219+ container = fmt .Sprintf ("run-command-test-%d" , rand .New (rand .NewSource (time .Now ().UnixNano ())).Int63 ())
220+ )
221+
222+ containerReference := blobStorageClient .GetContainerReference (container )
223+ _ , err = containerReference .DeleteIfExists (nil )
224+ require .Nil (t , err )
225+ _ , err = containerReference .CreateIfNotExists (& storage.CreateContainerOptions {Access : storage .ContainerAccessTypePrivate })
226+ require .Nil (t , err )
227+ defer containerReference .Delete (nil )
228+
229+ blobReference := containerReference .GetBlobReference (name )
230+ require .Nil (t , blobReference .PutAppendBlob (nil ))
231+ require .Nil (t , blobReference .AppendBlock (content , nil ))
232+
233+ // Generate SAS URL for the blob
234+ d := NewBlobDownload (acct , key , blobutil.AzureBlobRef {
235+ Container : container ,
236+ Blob : name ,
237+ StorageBase : base ,
238+ })
239+ v , ok := d .(blobDownload )
240+ require .True (t , ok )
241+ sasURL , err := v .getURL ()
242+ require .Nil (t , err )
243+
244+ // Parse the SAS URL to separate URI from SAS token
245+ blobURI := fmt .Sprintf ("https://%s.blob.%s/%s/%s" , acct , base , container , name )
246+ sasToken := sasURL [len (blobURI ):] // Everything after the base URI is the SAS token
247+
248+ // Download the blob using GetSASBlob
249+ tmpDir , err := ioutil .TempDir ("" , "nested-test-" )
250+ require .Nil (t , err )
251+ defer os .RemoveAll (tmpDir )
252+
253+ scriptFilePath , err := GetSASBlob (blobURI , sasToken , tmpDir )
254+ require .Nil (t , err )
255+
256+ // Verify that the file was downloaded with correct content
257+ result , err := ioutil .ReadFile (scriptFilePath )
258+ require .Nil (t , err )
259+ require .EqualValues (t , content , result , "downloaded content should match" )
260+
261+ // Verify that the file was created
262+ require .Contains (t , scriptFilePath , tmpDir , "file path should be in temp directory" )
263+
264+ // Verify the file exists and is not a directory
265+ fileInfo , err := os .Stat (scriptFilePath )
266+ require .Nil (t , err )
267+ require .False (t , fileInfo .IsDir (), "should be a file, not a directory" )
268+ }
269+
203270func Test_blobAppend_actualBlob (t * testing.T ) {
204271 // Before running the test locally prepare storage account and set the following env variables:
205272 // export AZURE_STORAGE_BLOB="https://atanas.blob.core.windows.net/con1/output5.txt"
0 commit comments