|
1 | 1 | package fabric |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "archive/tar" |
| 5 | + "bytes" |
| 6 | + "compress/gzip" |
4 | 7 | "context" |
5 | 8 | "fmt" |
6 | 9 | "os" |
@@ -404,3 +407,141 @@ func TestRegisterIdentity(t *testing.T) { |
404 | 407 | }) |
405 | 408 |
|
406 | 409 | } |
| 410 | + |
| 411 | +func TestValidateChaincodePackage(t *testing.T) { |
| 412 | + p := &FabricProvider{} |
| 413 | + |
| 414 | + // Helper function to create a valid tar.gz file |
| 415 | + createValidTarGz := func(t *testing.T, filename string) { |
| 416 | + var buf bytes.Buffer |
| 417 | + gzWriter := gzip.NewWriter(&buf) |
| 418 | + tarWriter := tar.NewWriter(gzWriter) |
| 419 | + |
| 420 | + // Add a file to the tar archive |
| 421 | + content := []byte("test chaincode content") |
| 422 | + header := &tar.Header{ |
| 423 | + Name: "metadata.json", |
| 424 | + Mode: 0644, |
| 425 | + Size: int64(len(content)), |
| 426 | + } |
| 427 | + err := tarWriter.WriteHeader(header) |
| 428 | + assert.NoError(t, err) |
| 429 | + _, err = tarWriter.Write(content) |
| 430 | + assert.NoError(t, err) |
| 431 | + |
| 432 | + err = tarWriter.Close() |
| 433 | + assert.NoError(t, err) |
| 434 | + err = gzWriter.Close() |
| 435 | + assert.NoError(t, err) |
| 436 | + |
| 437 | + err = os.WriteFile(filename, buf.Bytes(), 0644) |
| 438 | + assert.NoError(t, err) |
| 439 | + } |
| 440 | + |
| 441 | + t.Run("valid tar.gz file", func(t *testing.T) { |
| 442 | + tmpDir := t.TempDir() |
| 443 | + validTarGzFile := filepath.Join(tmpDir, "valid.tar.gz") |
| 444 | + createValidTarGz(t, validTarGzFile) |
| 445 | + |
| 446 | + err := p.validateChaincodePackage(validTarGzFile) |
| 447 | + assert.NoError(t, err) |
| 448 | + }) |
| 449 | + |
| 450 | + t.Run("file not found", func(t *testing.T) { |
| 451 | + err := p.validateChaincodePackage("/nonexistent/path/chaincode.tar.gz") |
| 452 | + assert.Error(t, err) |
| 453 | + assert.Contains(t, err.Error(), "chaincode package file not found") |
| 454 | + }) |
| 455 | + |
| 456 | + t.Run("path is a directory", func(t *testing.T) { |
| 457 | + tmpDir := t.TempDir() |
| 458 | + err := p.validateChaincodePackage(tmpDir) |
| 459 | + assert.Error(t, err) |
| 460 | + assert.Contains(t, err.Error(), "chaincode package path is a directory") |
| 461 | + }) |
| 462 | + |
| 463 | + t.Run("invalid - plain text file", func(t *testing.T) { |
| 464 | + tmpDir := t.TempDir() |
| 465 | + plainTextFile := filepath.Join(tmpDir, "plain.txt") |
| 466 | + err := os.WriteFile(plainTextFile, []byte("this is not a gzip file"), 0644) |
| 467 | + assert.NoError(t, err) |
| 468 | + |
| 469 | + err = p.validateChaincodePackage(plainTextFile) |
| 470 | + assert.Error(t, err) |
| 471 | + assert.Contains(t, err.Error(), "invalid chaincode package file format") |
| 472 | + assert.Contains(t, err.Error(), "does not appear to be a valid gzip file") |
| 473 | + }) |
| 474 | + |
| 475 | + t.Run("invalid - zip file", func(t *testing.T) { |
| 476 | + tmpDir := t.TempDir() |
| 477 | + // ZIP files start with PK (0x50, 0x4B) |
| 478 | + zipLikeFile := filepath.Join(tmpDir, "fake.zip") |
| 479 | + err := os.WriteFile(zipLikeFile, []byte{0x50, 0x4B, 0x03, 0x04, 0x00, 0x00}, 0644) |
| 480 | + assert.NoError(t, err) |
| 481 | + |
| 482 | + err = p.validateChaincodePackage(zipLikeFile) |
| 483 | + assert.Error(t, err) |
| 484 | + assert.Contains(t, err.Error(), "invalid chaincode package file format") |
| 485 | + }) |
| 486 | + |
| 487 | + t.Run("invalid - random binary", func(t *testing.T) { |
| 488 | + tmpDir := t.TempDir() |
| 489 | + randomFile := filepath.Join(tmpDir, "random.bin") |
| 490 | + err := os.WriteFile(randomFile, []byte{0xDE, 0xAD, 0xBE, 0xEF}, 0644) |
| 491 | + assert.NoError(t, err) |
| 492 | + |
| 493 | + err = p.validateChaincodePackage(randomFile) |
| 494 | + assert.Error(t, err) |
| 495 | + assert.Contains(t, err.Error(), "invalid chaincode package file format") |
| 496 | + }) |
| 497 | + |
| 498 | + t.Run("invalid - gzip but not tar (plain gzipped content)", func(t *testing.T) { |
| 499 | + tmpDir := t.TempDir() |
| 500 | + gzipOnlyFile := filepath.Join(tmpDir, "gzip_only.gz") |
| 501 | + |
| 502 | + var buf bytes.Buffer |
| 503 | + gzWriter := gzip.NewWriter(&buf) |
| 504 | + _, err := gzWriter.Write([]byte("this is gzipped but not a tar archive")) |
| 505 | + assert.NoError(t, err) |
| 506 | + err = gzWriter.Close() |
| 507 | + assert.NoError(t, err) |
| 508 | + |
| 509 | + err = os.WriteFile(gzipOnlyFile, buf.Bytes(), 0644) |
| 510 | + assert.NoError(t, err) |
| 511 | + |
| 512 | + err = p.validateChaincodePackage(gzipOnlyFile) |
| 513 | + assert.Error(t, err) |
| 514 | + assert.Contains(t, err.Error(), "does not contain a valid tar archive") |
| 515 | + }) |
| 516 | + |
| 517 | + t.Run("invalid - empty tar.gz", func(t *testing.T) { |
| 518 | + tmpDir := t.TempDir() |
| 519 | + emptyTarGzFile := filepath.Join(tmpDir, "empty.tar.gz") |
| 520 | + |
| 521 | + var buf bytes.Buffer |
| 522 | + gzWriter := gzip.NewWriter(&buf) |
| 523 | + tarWriter := tar.NewWriter(gzWriter) |
| 524 | + // Close without adding any files |
| 525 | + err := tarWriter.Close() |
| 526 | + assert.NoError(t, err) |
| 527 | + err = gzWriter.Close() |
| 528 | + assert.NoError(t, err) |
| 529 | + |
| 530 | + err = os.WriteFile(emptyTarGzFile, buf.Bytes(), 0644) |
| 531 | + assert.NoError(t, err) |
| 532 | + |
| 533 | + err = p.validateChaincodePackage(emptyTarGzFile) |
| 534 | + assert.Error(t, err) |
| 535 | + assert.Contains(t, err.Error(), "tar.gz archive is empty") |
| 536 | + }) |
| 537 | + |
| 538 | + t.Run("invalid - empty file", func(t *testing.T) { |
| 539 | + tmpDir := t.TempDir() |
| 540 | + emptyFile := filepath.Join(tmpDir, "empty.tar.gz") |
| 541 | + err := os.WriteFile(emptyFile, []byte{}, 0644) |
| 542 | + assert.NoError(t, err) |
| 543 | + |
| 544 | + err = p.validateChaincodePackage(emptyFile) |
| 545 | + assert.Error(t, err) |
| 546 | + }) |
| 547 | +} |
0 commit comments