github.com/snowflakedb/gosnowflake@v1.9.0/file_transfer_agent_test.go (about) 1 // Copyright (c) 2022 Snowflake Computing Inc. All rights reserved. 2 3 package gosnowflake 4 5 import ( 6 "bytes" 7 "context" 8 "errors" 9 "fmt" 10 "io" 11 "net/url" 12 "os" 13 "path" 14 "path/filepath" 15 "strings" 16 "testing" 17 "time" 18 19 "github.com/aws/smithy-go" 20 ) 21 22 type tcFilePath struct { 23 command string 24 path string 25 } 26 27 func TestGetBucketAccelerateConfiguration(t *testing.T) { 28 if runningOnGithubAction() { 29 t.Skip("Should be run against an account in AWS EU North1 region.") 30 } 31 runSnowflakeConnTest(t, func(sct *SCTest) { 32 sfa := &snowflakeFileTransferAgent{ 33 sc: sct.sc, 34 commandType: uploadCommand, 35 srcFiles: make([]string, 0), 36 data: &execResponseData{ 37 SrcLocations: make([]string, 0), 38 }, 39 } 40 if err := sfa.transferAccelerateConfig(); err != nil { 41 var ae smithy.APIError 42 if errors.As(err, &ae) { 43 if ae.ErrorCode() == "MethodNotAllowed" { 44 t.Fatalf("should have ignored 405 error: %v", err) 45 } 46 } 47 } 48 }) 49 } 50 51 func TestUnitDownloadWithInvalidLocalPath(t *testing.T) { 52 tmpDir, err := os.MkdirTemp("", "data") 53 if err != nil { 54 t.Error(err) 55 } 56 defer os.RemoveAll(tmpDir) 57 testData := filepath.Join(tmpDir, "data.txt") 58 f, err := os.Create(testData) 59 if err != nil { 60 t.Error(err) 61 } 62 f.WriteString("test1,test2\ntest3,test4\n") 63 f.Close() 64 65 runDBTest(t, func(dbt *DBTest) { 66 if _, err = dbt.exec("use role sysadmin"); err != nil { 67 t.Skip("snowflake admin account not accessible") 68 } 69 dbt.mustExec("rm @~/test_get") 70 sqlText := fmt.Sprintf("put file://%v @~/test_get", testData) 71 sqlText = strings.ReplaceAll(sqlText, "\\", "\\\\") 72 dbt.mustExec(sqlText) 73 74 sqlText = fmt.Sprintf("get @~/test_get/data.txt file://%v\\get", tmpDir) 75 if _, err = dbt.query(sqlText); err == nil { 76 t.Fatalf("should return local path not directory error.") 77 } 78 dbt.mustExec("rm @~/test_get") 79 }) 80 } 81 func TestUnitGetLocalFilePathFromCommand(t *testing.T) { 82 runSnowflakeConnTest(t, func(sct *SCTest) { 83 sfa := &snowflakeFileTransferAgent{ 84 sc: sct.sc, 85 commandType: uploadCommand, 86 srcFiles: make([]string, 0), 87 data: &execResponseData{ 88 SrcLocations: make([]string, 0), 89 }, 90 } 91 testcases := []tcFilePath{ 92 {"PUT file:///tmp/my_data_file.txt @~ overwrite=true", "/tmp/my_data_file.txt"}, 93 {"PUT 'file:///tmp/my_data_file.txt' @~ overwrite=true", "/tmp/my_data_file.txt"}, 94 {"PUT file:///tmp/sub_dir/my_data_file.txt\n @~ overwrite=true", "/tmp/sub_dir/my_data_file.txt"}, 95 {"PUT file:///tmp/my_data_file.txt @~ overwrite=true", "/tmp/my_data_file.txt"}, 96 {"", ""}, 97 {"PUT 'file2:///tmp/my_data_file.txt' @~ overwrite=true", ""}, 98 } 99 for _, test := range testcases { 100 t.Run(test.command, func(t *testing.T) { 101 path := sfa.getLocalFilePathFromCommand(test.command) 102 if path != test.path { 103 t.Fatalf("unexpected file path. expected: %v, but got: %v", test.path, path) 104 } 105 }) 106 } 107 }) 108 } 109 110 func TestUnitProcessFileCompressionType(t *testing.T) { 111 runSnowflakeConnTest(t, func(sct *SCTest) { 112 sfa := &snowflakeFileTransferAgent{ 113 sc: sct.sc, 114 commandType: uploadCommand, 115 srcFiles: make([]string, 0), 116 } 117 testcases := []struct { 118 srcCompression string 119 }{ 120 {"none"}, 121 {"auto_detect"}, 122 {"gzip"}, 123 } 124 125 for _, test := range testcases { 126 t.Run(test.srcCompression, func(t *testing.T) { 127 sfa.srcCompression = test.srcCompression 128 err := sfa.processFileCompressionType() 129 if err != nil { 130 t.Fatalf("failed to process file compression") 131 } 132 }) 133 } 134 135 // test invalid compression type error 136 sfa.srcCompression = "gz" 137 data := &execResponseData{ 138 SQLState: "S00087", 139 QueryID: "01aa2e8b-0405-ab7c-0000-53b10632f626", 140 } 141 sfa.data = data 142 err := sfa.processFileCompressionType() 143 if err == nil { 144 t.Fatal("should have failed") 145 } 146 driverErr, ok := err.(*SnowflakeError) 147 if !ok { 148 t.Fatalf("should be snowflake error. err: %v", err) 149 } 150 if driverErr.Number != ErrCompressionNotSupported { 151 t.Fatalf("unexpected error code. expected: %v, got: %v", ErrCompressionNotSupported, driverErr.Number) 152 } 153 }) 154 } 155 156 func TestParseCommandWithInvalidStageLocation(t *testing.T) { 157 runSnowflakeConnTest(t, func(sct *SCTest) { 158 sfa := &snowflakeFileTransferAgent{ 159 sc: sct.sc, 160 commandType: uploadCommand, 161 srcFiles: make([]string, 0), 162 data: &execResponseData{ 163 SrcLocations: make([]string, 0), 164 }, 165 } 166 167 err := sfa.parseCommand() 168 if err == nil { 169 t.Fatal("should have raised an error") 170 } 171 driverErr, ok := err.(*SnowflakeError) 172 if !ok || driverErr.Number != ErrInvalidStageLocation { 173 t.Fatalf("unexpected error code. expected: %v, got: %v", ErrInvalidStageLocation, driverErr.Number) 174 } 175 }) 176 } 177 178 func TestParseCommandEncryptionMaterialMismatchError(t *testing.T) { 179 runSnowflakeConnTest(t, func(sct *SCTest) { 180 mockEncMaterial1 := snowflakeFileEncryption{ 181 QueryStageMasterKey: "abCdEFO0upIT36dAxGsa0w==", 182 QueryID: "01abc874-0406-1bf0-0000-53b10668e056", 183 SMKID: 92019681909886, 184 } 185 186 mockEncMaterial2 := snowflakeFileEncryption{ 187 QueryStageMasterKey: "abCdEFO0upIT36dAxGsa0w==", 188 QueryID: "01abc874-0406-1bf0-0000-53b10668e056", 189 SMKID: 92019681909886, 190 } 191 192 sfa := &snowflakeFileTransferAgent{ 193 sc: sct.sc, 194 commandType: uploadCommand, 195 srcFiles: make([]string, 0), 196 data: &execResponseData{ 197 SrcLocations: []string{"/tmp/uploads"}, 198 EncryptionMaterial: encryptionWrapper{ 199 snowflakeFileEncryption: mockEncMaterial1, 200 EncryptionMaterials: []snowflakeFileEncryption{mockEncMaterial1, mockEncMaterial2}, 201 }, 202 }, 203 } 204 205 err := sfa.parseCommand() 206 if err == nil { 207 t.Fatal("should have raised an error") 208 } 209 driverErr, ok := err.(*SnowflakeError) 210 if !ok || driverErr.Number != ErrInternalNotMatchEncryptMaterial { 211 t.Fatalf("unexpected error code. expected: %v, got: %v", ErrInternalNotMatchEncryptMaterial, driverErr.Number) 212 } 213 }) 214 } 215 216 func TestParseCommandInvalidStorageClientException(t *testing.T) { 217 runSnowflakeConnTest(t, func(sct *SCTest) { 218 tmpDir, err := os.MkdirTemp("", "abc") 219 if err != nil { 220 t.Error(err) 221 } 222 mockEncMaterial1 := snowflakeFileEncryption{ 223 QueryStageMasterKey: "abCdEFO0upIT36dAxGsa0w==", 224 QueryID: "01abc874-0406-1bf0-0000-53b10668e056", 225 SMKID: 92019681909886, 226 } 227 228 sfa := &snowflakeFileTransferAgent{ 229 sc: sct.sc, 230 commandType: uploadCommand, 231 srcFiles: make([]string, 0), 232 data: &execResponseData{ 233 SrcLocations: []string{"/tmp/uploads"}, 234 LocalLocation: tmpDir, 235 EncryptionMaterial: encryptionWrapper{ 236 snowflakeFileEncryption: mockEncMaterial1, 237 EncryptionMaterials: []snowflakeFileEncryption{mockEncMaterial1}, 238 }, 239 }, 240 } 241 242 err = sfa.parseCommand() 243 if err == nil { 244 t.Fatal("should have raised an error") 245 } 246 driverErr, ok := err.(*SnowflakeError) 247 if !ok || driverErr.Number != ErrInvalidStageFs { 248 t.Fatalf("unexpected error code. expected: %v, got: %v", ErrInvalidStageFs, driverErr.Number) 249 } 250 }) 251 } 252 253 func TestInitFileMetadataError(t *testing.T) { 254 runSnowflakeConnTest(t, func(sct *SCTest) { 255 sfa := &snowflakeFileTransferAgent{ 256 sc: sct.sc, 257 commandType: uploadCommand, 258 srcFiles: []string{"fileDoesNotExist.txt"}, 259 data: &execResponseData{ 260 SQLState: "123456", 261 QueryID: "01aa2e8b-0405-ab7c-0000-53b10632f626", 262 }, 263 } 264 265 err := sfa.initFileMetadata() 266 if err == nil { 267 t.Fatal("should have raised an error") 268 } 269 270 driverErr, ok := err.(*SnowflakeError) 271 if !ok || driverErr.Number != ErrFileNotExists { 272 t.Fatalf("unexpected error code. expected: %v, got: %v", ErrFileNotExists, driverErr.Number) 273 } 274 275 tmpDir, err := os.MkdirTemp("", "data") 276 if err != nil { 277 t.Error(err) 278 } 279 defer os.RemoveAll(tmpDir) 280 sfa.srcFiles = []string{tmpDir} 281 282 err = sfa.initFileMetadata() 283 if err == nil { 284 t.Fatal("should have raised an error") 285 } 286 287 driverErr, ok = err.(*SnowflakeError) 288 if !ok || driverErr.Number != ErrFileNotExists { 289 t.Fatalf("unexpected error code. expected: %v, got: %v", ErrFileNotExists, driverErr.Number) 290 } 291 }) 292 } 293 294 func TestUpdateMetadataWithPresignedUrl(t *testing.T) { 295 runSnowflakeConnTest(t, func(sct *SCTest) { 296 info := execResponseStageInfo{ 297 Location: "gcs-blob/storage/users/456/", 298 LocationType: "GCS", 299 } 300 301 dir, err := os.Getwd() 302 if err != nil { 303 t.Error(err) 304 } 305 306 testURL := "https://storage.google.com/gcs-blob/storage/users/456?Signature=testsignature123" 307 308 presignedURLMock := func(_ context.Context, _ *snowflakeRestful, 309 _ *url.Values, _ map[string]string, _ []byte, _ time.Duration, 310 requestID UUID, _ *Config) (*execResponse, error) { 311 // ensure the same requestID from context is used 312 if len(requestID) == 0 { 313 t.Fatal("requestID is empty") 314 } 315 dd := &execResponseData{ 316 QueryID: "01aa2e8b-0405-ab7c-0000-53b10632f626", 317 Command: string(uploadCommand), 318 StageInfo: execResponseStageInfo{ 319 LocationType: "GCS", 320 Location: "gcspuscentral1-4506459564-stage/users/456", 321 Path: "users/456", 322 Region: "US_CENTRAL1", 323 PresignedURL: testURL, 324 }, 325 } 326 return &execResponse{ 327 Data: *dd, 328 Message: "", 329 Code: "0", 330 Success: true, 331 }, nil 332 } 333 334 gcsCli, err := new(snowflakeGcsClient).createClient(&info, false) 335 if err != nil { 336 t.Error(err) 337 } 338 uploadMeta := fileMetadata{ 339 name: "data1.txt.gz", 340 stageLocationType: "GCS", 341 noSleepingTime: true, 342 client: gcsCli, 343 sha256Digest: "123456789abcdef", 344 stageInfo: &info, 345 dstFileName: "data1.txt.gz", 346 srcFileName: path.Join(dir, "/test_data/data1.txt"), 347 overwrite: true, 348 options: &SnowflakeFileTransferOptions{ 349 MultiPartThreshold: dataSizeThreshold, 350 }, 351 } 352 353 sct.sc.rest.FuncPostQuery = presignedURLMock 354 sfa := &snowflakeFileTransferAgent{ 355 sc: sct.sc, 356 commandType: uploadCommand, 357 command: "put file:///tmp/test_data/data1.txt @~", 358 stageLocationType: gcsClient, 359 fileMetadata: []*fileMetadata{&uploadMeta}, 360 } 361 362 err = sfa.updateFileMetadataWithPresignedURL() 363 if err != nil { 364 t.Error(err) 365 } 366 if testURL != sfa.fileMetadata[0].presignedURL.String() { 367 t.Fatalf("failed to update metadata with presigned url. expected: %v. got: %v", testURL, sfa.fileMetadata[0].presignedURL.String()) 368 } 369 }) 370 } 371 372 func TestUpdateMetadataWithPresignedUrlForDownload(t *testing.T) { 373 runSnowflakeConnTest(t, func(sct *SCTest) { 374 info := execResponseStageInfo{ 375 Location: "gcs-blob/storage/users/456/", 376 LocationType: "GCS", 377 } 378 379 dir, err := os.Getwd() 380 if err != nil { 381 t.Error(err) 382 } 383 384 testURL := "https://storage.google.com/gcs-blob/storage/users/456?Signature=testsignature123" 385 386 gcsCli, err := new(snowflakeGcsClient).createClient(&info, false) 387 if err != nil { 388 t.Error(err) 389 } 390 downloadMeta := fileMetadata{ 391 name: "data1.txt.gz", 392 stageLocationType: "GCS", 393 noSleepingTime: true, 394 client: gcsCli, 395 stageInfo: &info, 396 dstFileName: "data1.txt.gz", 397 overwrite: true, 398 srcFileName: "data1.txt.gz", 399 localLocation: dir, 400 } 401 402 sfa := &snowflakeFileTransferAgent{ 403 sc: sct.sc, 404 commandType: downloadCommand, 405 command: "get @~/data1.txt.gz file:///tmp/testData", 406 stageLocationType: gcsClient, 407 fileMetadata: []*fileMetadata{&downloadMeta}, 408 presignedURLs: []string{testURL}, 409 } 410 411 err = sfa.updateFileMetadataWithPresignedURL() 412 if err != nil { 413 t.Error(err) 414 } 415 if testURL != sfa.fileMetadata[0].presignedURL.String() { 416 t.Fatalf("failed to update metadata with presigned url. expected: %v. got: %v", testURL, sfa.fileMetadata[0].presignedURL.String()) 417 } 418 }) 419 } 420 421 func TestUpdateMetadataWithPresignedUrlError(t *testing.T) { 422 runSnowflakeConnTest(t, func(sct *SCTest) { 423 sfa := &snowflakeFileTransferAgent{ 424 sc: sct.sc, 425 command: "get @~/data1.txt.gz file:///tmp/testData", 426 stageLocationType: gcsClient, 427 data: &execResponseData{ 428 SQLState: "123456", 429 QueryID: "01aa2e8b-0405-ab7c-0000-53b10632f626", 430 }, 431 } 432 433 err := sfa.updateFileMetadataWithPresignedURL() 434 if err == nil { 435 t.Fatal("should have raised an error") 436 } 437 driverErr, ok := err.(*SnowflakeError) 438 if !ok || driverErr.Number != ErrCommandNotRecognized { 439 t.Fatalf("unexpected error code. expected: %v, got: %v", ErrCommandNotRecognized, driverErr.Number) 440 } 441 }) 442 } 443 444 func TestUploadWhenFilesystemReadOnlyError(t *testing.T) { 445 if isWindows { 446 t.Skip("permission model is different") 447 } 448 449 var err error 450 roPath := t.TempDir() 451 if err != nil { 452 t.Fatal(err) 453 } 454 455 // Set the temp directory to read only 456 err = os.Chmod(roPath, 0444) 457 if err != nil { 458 t.Fatal(err) 459 } 460 461 info := execResponseStageInfo{ 462 Location: "gcs-blob/storage/users/456/", 463 LocationType: "GCS", 464 } 465 dir, err := os.Getwd() 466 if err != nil { 467 t.Error(err) 468 } 469 470 // Make sure that the test uses read only directory 471 t.Setenv("TMPDIR", roPath) 472 473 uploadMeta := fileMetadata{ 474 name: "data1.txt.gz", 475 stageLocationType: "GCS", 476 noSleepingTime: true, 477 client: gcsClient, 478 sha256Digest: "123456789abcdef", 479 stageInfo: &info, 480 dstFileName: "data1.txt.gz", 481 srcFileName: path.Join(dir, "/test_data/data1.txt"), 482 overwrite: true, 483 options: &SnowflakeFileTransferOptions{ 484 MultiPartThreshold: dataSizeThreshold, 485 }, 486 } 487 488 sfa := &snowflakeFileTransferAgent{ 489 sc: &snowflakeConn{ 490 cfg: &Config{}, 491 }, 492 commandType: uploadCommand, 493 command: "put file:///tmp/test_data/data1.txt @~", 494 stageLocationType: gcsClient, 495 fileMetadata: []*fileMetadata{&uploadMeta}, 496 parallel: 1, 497 } 498 499 err = sfa.uploadFilesParallel([]*fileMetadata{&uploadMeta}) 500 if err == nil { 501 t.Fatal("should error when the filesystem is read only") 502 } 503 if !strings.Contains(err.Error(), "errors during file upload:\nmkdir") { 504 t.Fatalf("should error when creating the temporary directory. Instead errored with: %v", err) 505 } 506 } 507 508 func TestUnitUpdateProgess(t *testing.T) { 509 var b bytes.Buffer 510 buf := io.Writer(&b) 511 buf.Write([]byte("testing")) 512 513 spp := &snowflakeProgressPercentage{ 514 filename: "test.txt", 515 fileSize: float64(1500), 516 outputStream: &buf, 517 showProgressBar: true, 518 done: false, 519 } 520 521 spp.call(0) 522 if spp.done != false { 523 t.Fatal("should not be done.") 524 } 525 526 if spp.seenSoFar != 0 { 527 t.Fatalf("expected seenSoFar to be 0 but was %v", spp.seenSoFar) 528 } 529 530 spp.call(1516) 531 if spp.done != true { 532 t.Fatal("should be done after updating progess") 533 } 534 } 535 536 func TestCustomTmpDirPath(t *testing.T) { 537 tmpDir, err := os.MkdirTemp("", "") 538 if err != nil { 539 t.Fatalf("cannot create temp directory: %v", err) 540 } 541 defer os.RemoveAll(tmpDir) 542 uploadFile := filepath.Join(tmpDir, "data.txt") 543 f, err := os.Create(uploadFile) 544 if err != nil { 545 t.Error(err) 546 } 547 f.WriteString("test1,test2\ntest3,test4\n") 548 f.Close() 549 550 uploadMeta := &fileMetadata{ 551 name: "data.txt.gz", 552 stageLocationType: "local", 553 noSleepingTime: true, 554 client: local, 555 sha256Digest: "123456789abcdef", 556 stageInfo: &execResponseStageInfo{ 557 Location: tmpDir, 558 LocationType: "local", 559 }, 560 dstFileName: "data.txt.gz", 561 srcFileName: uploadFile, 562 overwrite: true, 563 options: &SnowflakeFileTransferOptions{ 564 MultiPartThreshold: dataSizeThreshold, 565 }, 566 } 567 568 downloadFile := filepath.Join(tmpDir, "download.txt") 569 downloadMeta := &fileMetadata{ 570 name: "data.txt.gz", 571 stageLocationType: "local", 572 noSleepingTime: true, 573 client: local, 574 sha256Digest: "123456789abcdef", 575 stageInfo: &execResponseStageInfo{ 576 Location: tmpDir, 577 LocationType: "local", 578 }, 579 srcFileName: "data.txt.gz", 580 dstFileName: downloadFile, 581 overwrite: true, 582 options: &SnowflakeFileTransferOptions{ 583 MultiPartThreshold: dataSizeThreshold, 584 }, 585 } 586 587 sfa := snowflakeFileTransferAgent{ 588 sc: &snowflakeConn{ 589 cfg: &Config{ 590 TmpDirPath: tmpDir, 591 }, 592 }, 593 stageLocationType: local, 594 } 595 _, err = sfa.uploadOneFile(uploadMeta) 596 if err != nil { 597 t.Fatal(err) 598 } 599 _, err = sfa.downloadOneFile(downloadMeta) 600 if err != nil { 601 t.Fatal(err) 602 } 603 defer os.Remove("download.txt") 604 } 605 606 func TestReadonlyTmpDirPathShouldFail(t *testing.T) { 607 if isWindows { 608 t.Skip("permission model is different") 609 } 610 tmpDir, err := os.MkdirTemp("", "") 611 if err != nil { 612 t.Fatalf("cannot create temp directory: %v", err) 613 } 614 defer os.RemoveAll(tmpDir) 615 616 uploadFile := filepath.Join(tmpDir, "data.txt") 617 f, err := os.Create(uploadFile) 618 if err != nil { 619 t.Error(err) 620 } 621 f.WriteString("test1,test2\ntest3,test4\n") 622 f.Close() 623 624 err = os.Chmod(tmpDir, 0400) 625 if err != nil { 626 t.Fatalf("cannot mark directory as readonly: %v", err) 627 } 628 defer os.Chmod(tmpDir, 0600) 629 630 uploadMeta := &fileMetadata{ 631 name: "data.txt.gz", 632 stageLocationType: "local", 633 noSleepingTime: true, 634 client: local, 635 sha256Digest: "123456789abcdef", 636 stageInfo: &execResponseStageInfo{ 637 Location: tmpDir, 638 LocationType: "local", 639 }, 640 dstFileName: "data.txt.gz", 641 srcFileName: uploadFile, 642 overwrite: true, 643 options: &SnowflakeFileTransferOptions{ 644 MultiPartThreshold: dataSizeThreshold, 645 }, 646 } 647 648 sfa := snowflakeFileTransferAgent{ 649 sc: &snowflakeConn{ 650 cfg: &Config{ 651 TmpDirPath: tmpDir, 652 }, 653 }, 654 stageLocationType: local, 655 } 656 _, err = sfa.uploadOneFile(uploadMeta) 657 if err == nil { 658 t.Fatalf("should not upload file as temporary directory is not readable") 659 } 660 } 661 662 func TestUploadDownloadOneFileRequireCompress(t *testing.T) { 663 testUploadDownloadOneFile(t, false) 664 } 665 666 func TestUploadDownloadOneFileRequireCompressStream(t *testing.T) { 667 testUploadDownloadOneFile(t, true) 668 } 669 670 func testUploadDownloadOneFile(t *testing.T, isStream bool) { 671 tmpDir, err := os.MkdirTemp("", "data") 672 if err != nil { 673 t.Fatalf("cannot create temp directory: %v", err) 674 } 675 defer os.RemoveAll(tmpDir) 676 uploadFile := filepath.Join(tmpDir, "data.txt") 677 f, err := os.Create(uploadFile) 678 if err != nil { 679 t.Error(err) 680 } 681 f.WriteString("test1,test2\ntest3,test4\n") 682 f.Close() 683 684 uploadMeta := &fileMetadata{ 685 name: "data.txt.gz", 686 stageLocationType: "local", 687 noSleepingTime: true, 688 client: local, 689 sha256Digest: "123456789abcdef", 690 stageInfo: &execResponseStageInfo{ 691 Location: tmpDir, 692 LocationType: "local", 693 }, 694 dstFileName: "data.txt.gz", 695 srcFileName: uploadFile, 696 overwrite: true, 697 options: &SnowflakeFileTransferOptions{ 698 MultiPartThreshold: dataSizeThreshold, 699 }, 700 requireCompress: true, 701 } 702 703 downloadFile := filepath.Join(tmpDir, "download.txt") 704 downloadMeta := &fileMetadata{ 705 name: "data.txt.gz", 706 stageLocationType: "local", 707 noSleepingTime: true, 708 client: local, 709 sha256Digest: "123456789abcdef", 710 stageInfo: &execResponseStageInfo{ 711 Location: tmpDir, 712 LocationType: "local", 713 }, 714 srcFileName: "data.txt.gz", 715 dstFileName: downloadFile, 716 overwrite: true, 717 options: &SnowflakeFileTransferOptions{ 718 MultiPartThreshold: dataSizeThreshold, 719 }, 720 } 721 722 sfa := snowflakeFileTransferAgent{ 723 sc: &snowflakeConn{ 724 cfg: &Config{ 725 TmpDirPath: tmpDir, 726 }, 727 }, 728 stageLocationType: local, 729 } 730 731 if isStream { 732 fileStream, _ := os.Open(uploadFile) 733 ctx := WithFileStream(context.Background(), fileStream) 734 uploadMeta.srcStream = getFileStream(ctx) 735 } 736 737 _, err = sfa.uploadOneFile(uploadMeta) 738 if err != nil { 739 t.Fatal(err) 740 } 741 if uploadMeta.resStatus != uploaded { 742 t.Fatalf("failed to upload file") 743 } 744 745 _, err = sfa.downloadOneFile(downloadMeta) 746 if err != nil { 747 t.Fatal(err) 748 } 749 defer os.Remove("download.txt") 750 if downloadMeta.resStatus != downloaded { 751 t.Fatalf("failed to download file") 752 } 753 }