Jitmisra opened a new pull request, #1050: URL: https://github.com/apache/incubator-seata-go/pull/1050
# What this PR does Fixes [#1049](https://github.com/apache/incubator-seata-go/issues/1049) — `CompressorSevenz` type was registered in `compressor_type.go` but never implemented, causing users who configure `"Sevenz"` compression to silently receive **no compression at all**. This PR: 1. **Implements the `Sevenz` compressor** in `7z_compress.go` using LZMA (the core algorithm behind 7-Zip) 2. **Adds the missing switch case** `CompressorSevenz` in `GetCompressor()` 3. **Adds unit tests** for `7z_compress.go`, `none_compressor.go`, and a table-driven test for `compressor_type.go` --- ## Which issue(s) this PR fixes Fixes [#1049](https://github.com/apache/incubator-seata-go/issues/1049) This is the **same class of bug** as [#1012](https://github.com/apache/incubator-seata-go/issues/1012) (fixed in [#1013](https://github.com/apache/incubator-seata-go/pull/1013)), where `Zip.GetCompressorType()` returned `CompressorZstd` instead of `CompressorZip`. --- ## Bug Explained (Before → After) ### Before (Broken) ```mermaid flowchart LR A["User configures\ncompressor: Sevenz"] --> B["GetCompressor()\ncalled"] B --> C{"switch on\nCompressorType"} C -->|"No matching case"| D["default:\nreturn NoneCompressor"] D --> E["❌ Data sent\nUNCOMPRESSED"] style A fill:#ff6b6b,color:#fff style D fill:#ff6b6b,color:#fff style E fill:#ff6b6b,color:#fff ``` ### After (Fixed) ```mermaid flowchart LR A["User configures\ncompressor: Sevenz"] --> B["GetCompressor()\ncalled"] B --> C{"switch on\nCompressorType"} C -->|"case CompressorSevenz"| D["return &Sevenz{}"] D --> E["✅ Data compressed\nusing LZMA"] style A fill:#51cf66,color:#fff style D fill:#51cf66,color:#fff style E fill:#51cf66,color:#fff ``` --- ## Compressor Architecture All compressors implement the same `Compressor` interface: ```mermaid classDiagram class Compressor { <<interface>> +Compress([]byte) ([]byte, error) +Decompress([]byte) ([]byte, error) +GetCompressorType() CompressorType } Compressor <|.. NoneCompressor Compressor <|.. Gzip Compressor <|.. Zip Compressor <|.. Sevenz : 🆕 NEW Compressor <|.. Bzip2 Compressor <|.. Lz4 Compressor <|.. Zstd Compressor <|.. Snappy Compressor <|.. DeflateCompress class Sevenz { +Compress(data []byte) ([]byte, error) +Decompress(data []byte) ([]byte, error) +GetCompressorType() CompressorType } note for Sevenz "Uses github.com/ulikunitz/xz/lzma\n(LZMA algorithm — core of 7-Zip)" ``` --- ## Changed Files | File | Type | Change | | ---------------------------------------- | -------- | ---------------------------------------------------------------------- | | `pkg/compressor/7z_compress.go` | Modified | Implemented `Sevenz` struct with LZMA `Compress`/`Decompress` methods | | `pkg/compressor/compressor_type.go` | Modified | Added `case CompressorSevenz: return &Sevenz{}` to `GetCompressor()` | | `pkg/compressor/7z_compress_test.go` | **New** | Roundtrip compress/decompress test + type assertion | | `pkg/compressor/none_compressor_test.go` | **New** | Pass-through verification + type assertion | | `pkg/compressor/compressor_type_test.go` | **New** | Table-driven test for all 9 `CompressorType` values + unknown fallback | | `go.mod` | Modified | Promoted `github.com/ulikunitz/xz` to direct dependency | | `go.sum` | Modified | Updated checksums | | `changes/dev.md` | Modified | Added changelog entry for #1049 | --- ## Key Code Changes ### 1. `7z_compress.go` — Sevenz Implementation ```go type Sevenz struct{} // Compress using LZMA algorithm (core of 7-Zip) func (s *Sevenz) Compress(data []byte) ([]byte, error) { var buffer bytes.Buffer writer, err := lzma.NewWriter(&buffer) if err != nil { return nil, err } if _, err := writer.Write(data); err != nil { return nil, err } if err := writer.Close(); err != nil { return nil, err } return buffer.Bytes(), nil } // Decompress using LZMA algorithm func (s *Sevenz) Decompress(data []byte) ([]byte, error) { reader, err := lzma.NewReader(bytes.NewReader(data)) if err != nil { return nil, err } return ioutil.ReadAll(reader) } func (s *Sevenz) GetCompressorType() CompressorType { return CompressorSevenz } ``` ### 2. `compressor_type.go` — Switch Case Addition ```diff case CompressorZip: return &Zip{} + case CompressorSevenz: + return &Sevenz{} case CompressorBzip2: return &Bzip2{} ``` ### 3. `compressor_type_test.go` — Table-Driven Test (Prevents Future Regressions) ```go func TestGetCompressor(t *testing.T) { tests := []struct { name string compressorType CompressorType wantType CompressorType }{ {"None compressor", CompressorNone, CompressorNone}, {"Gzip compressor", CompressorGzip, CompressorGzip}, {"Zip compressor", CompressorZip, CompressorZip}, {"Sevenz compressor", CompressorSevenz, CompressorSevenz}, // ← catches this bug {"Bzip2 compressor", CompressorBzip2, CompressorBzip2}, {"Lz4 compressor", CompressorLz4, CompressorLz4}, {"Deflate compressor", CompressorDeflate, CompressorDeflate}, {"Zstd compressor", CompressorZstd, CompressorZstd}, {"Snappy compressor", CompressorSnappy, CompressorSnappy}, {"Unknown falls back", CompressorType("Unknown"), CompressorNone}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { compressor := tt.compressorType.GetCompressor() assert.NotNil(t, compressor) assert.EqualValues(t, tt.wantType, compressor.GetCompressorType()) }) } } ``` --- ## Verification Results ### Unit Tests — 10/10 PASS ✅ ``` === RUN TestSevenzCompress --- PASS: TestSevenzCompress (0.00s) === RUN TestGetCompressor --- PASS: TestGetCompressor/None_compressor (0.00s) --- PASS: TestGetCompressor/Gzip_compressor (0.00s) --- PASS: TestGetCompressor/Zip_compressor (0.00s) --- PASS: TestGetCompressor/Sevenz_compressor (0.00s) --- PASS: TestGetCompressor/Bzip2_compressor (0.00s) --- PASS: TestGetCompressor/Lz4_compressor (0.00s) --- PASS: TestGetCompressor/Deflate_compressor (0.00s) --- PASS: TestGetCompressor/Zstd_compressor (0.00s) --- PASS: TestGetCompressor/Snappy_compressor (0.00s) --- PASS: TestGetCompressor/Unknown_compressor_falls_back_to_None (0.00s) --- PASS: TestGetCompressor (0.00s) === RUN TestNoneCompressorCompress --- PASS: TestNoneCompressorCompress (0.00s) PASS ok seata.apache.org/seata-go/v2/pkg/compressor 0.681s ``` ### Additional Checks | Check | Result | | ------------------------------- | --------------------------- | | `go vet` | ✅ Clean | | Race detector (`go test -race`) | ✅ Clean | | Code coverage | **77.2%** of statements | | License headers (ASF 2.0) | ✅ Present on all files | | Pattern consistency | ✅ Matches Bzip2/Gzip style | --- -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
