Skip to content

fix: implement CompressorSevenz and add missing compressor unit tests#1050

Closed
Jitmisra wants to merge 6 commits intoapache:masterfrom
Jitmisra:fix/compressor-sevenz-1049
Closed

fix: implement CompressorSevenz and add missing compressor unit tests#1050
Jitmisra wants to merge 6 commits intoapache:masterfrom
Jitmisra:fix/compressor-sevenz-1049

Conversation

@Jitmisra
Copy link
Copy Markdown

@Jitmisra Jitmisra commented Mar 1, 2026

What this PR does

Fixes #1049CompressorSevenz 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

This is the same class of bug as #1012 (fixed in #1013), where Zip.GetCompressorType() returned CompressorZstd instead of CompressorZip.


Bug Explained (Before → After)

Before (Broken)

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
Loading

After (Fixed)

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
Loading

Compressor Architecture

All compressors implement the same Compressor interface:

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)"
Loading

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

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

  case CompressorZip:
      return &Zip{}
+ case CompressorSevenz:
+     return &Sevenz{}
  case CompressorBzip2:
      return &Bzip2{}

3. compressor_type_test.go — Table-Driven Test (Prevents Future Regressions)

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

@github-actions github-actions Bot added bug Something isn't working coding documentation Improvements or additions to documentation enhancement New feature or request milestone and removed bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request labels Mar 1, 2026
@thunguo thunguo self-requested a review March 1, 2026 15:22
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Mar 1, 2026

Codecov Report

❌ Patch coverage is 56.52174% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.36%. Comparing base (9a11740) to head (a7e4cb6).

Files with missing lines Patch % Lines
pkg/compressor/7z_compress.go 52.38% 5 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1050      +/-   ##
==========================================
+ Coverage   57.18%   57.36%   +0.18%     
==========================================
  Files         267      268       +1     
  Lines       17526    17549      +23     
==========================================
+ Hits        10022    10067      +45     
+ Misses       6680     6653      -27     
- Partials      824      829       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread pkg/compressor/7z_compress.go Outdated
return nil, err
}

decompressed, err := ioutil.ReadAll(reader)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ioutil is deprecated. Wouldn't it be better to use io.ReadAll(reader) instead?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ioutil is deprecated. Wouldn't it be better to use io.ReadAll(reader) instead?

sure thanks

return nil, err
}

if err := writer.Close(); err != nil {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The write operation here throws an error, causing the Close operation to fail. Would defer be better?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure thanks

@thunguo
Copy link
Copy Markdown
Contributor

thunguo commented Mar 1, 2026

If you are interested in SeataGo or would like to continue contributing, you can add me on WeChat FinnTew

@Jitmisra Jitmisra force-pushed the fix/compressor-sevenz-1049 branch from 9013a65 to d015bab Compare March 1, 2026 16:26
@github-actions github-actions Bot added bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request labels Mar 1, 2026
@Jitmisra
Copy link
Copy Markdown
Author

Jitmisra commented Mar 1, 2026

If you are interested in SeataGo or would like to continue contributing, you can add me on WeChat FinnTew

Hi thunguo,

Thank you for offering to connect on WeChat. Unfortunately, WeChat isn’t available in my region, so I’m unable to use it.

Would it be possible to continue the discussion via email or any other platform you prefer?

I’m very interested in continuing to contribute to Seata-Go, and I’m especially keen on working on the GSoC multi-database AT support idea this year. I’d really appreciate the opportunity to discuss how I can prepare and contribute effectively.

Thank you again!

@Jitmisra Jitmisra force-pushed the fix/compressor-sevenz-1049 branch from d015bab to e07f5ac Compare March 1, 2026 16:39
@thunguo
Copy link
Copy Markdown
Contributor

thunguo commented Mar 1, 2026

If you are interested in SeataGo or would like to continue contributing, you can add me on WeChat FinnTew

Hi Feng,

Thank you for offering to connect on WeChat. Unfortunately, WeChat isn’t available in my region, so I’m unable to use it.

Would it be possible to continue the discussion via email or any other platform you prefer?

I’m very interested in continuing to contribute to Seata-Go, and I’m especially keen on working on the GSoC multi-database AT support idea this year. I’d really appreciate the opportunity to discuss how I can prepare and contribute effectively.

Thank you again!

Okay, the community is very welcoming to new contributors, you can join through tew@apache.org Contact me via email or through zfeng@apache.org Contact Feng, the mentor of the multi-database project, via email.

@Jitmisra
Copy link
Copy Markdown
Author

Jitmisra commented Mar 1, 2026

If you are interested in SeataGo or would like to continue contributing, you can add me on WeChat FinnTew

Hi Feng,
Thank you for offering to connect on WeChat. Unfortunately, WeChat isn’t available in my region, so I’m unable to use it.
Would it be possible to continue the discussion via email or any other platform you prefer?
I’m very interested in continuing to contribute to Seata-Go, and I’m especially keen on working on the GSoC multi-database AT support idea this year. I’d really appreciate the opportunity to discuss how I can prepare and contribute effectively.
Thank you again!

Okay, the community is very welcoming to new contributors, you can join through tew@apache.org Contact me via email or through zfeng@apache.org Contact Feng, the mentor of the multi-database project, via email.

Thank you very much for the guidance and for sharing the contact details.

I’ll reach out via email to continue the discussion and start contributing more actively to SeataGo.

I truly appreciate the welcoming environment of the community and look forward to contributing further.

Copy link
Copy Markdown
Contributor

@AlexStocks AlexStocks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: fix: implement CompressorSevenz and add missing compressor unit tests

评价

问题修复正确,实现了缺失的 CompressorSevenz,并添加了完整的单元测试。测试覆盖率达到 77.2%。

[P1] 规范级问题

1. pkg/compressor/7z_compress.go - 命名混淆

文件名为 7z_compress.go,但实际使用的是 LZMA 算法(来自 github.com/ulikunitz/xz/lzma):

import "github.com/ulikunitz/xz/lzma"

func (s *Sevenz) Compress(data []byte) ([]byte, error) {
    writer, err := lzma.NewWriter(&buffer)
    // ...
}

7z 格式支持多种算法(LZMA, LZMA2, PPMd 等),当前实现仅支持 LZMA。

建议

  • 重命名为 lzma_compress.go 并将 CompressorSevenz 改为 CompressorLzma
  • 或在注释中明确说明使用 LZMA 算法的原因
// Sevenz implements compression using LZMA algorithm.
// Note: This implementation uses the LZMA codec from xz library,
// which is the core algorithm used in 7-Zip. It does not produce
// actual .7z container format.
type Sevenz struct{}

2. 边界测试缺失

测试用例缺少:

  • 空数据压缩/解压
  • 超大数据(>1MB)压缩
  • 损坏数据解压错误处理

建议补充

func TestSevenzCompress_EmptyData(t *testing.T) {
    s := &Sevenz{}
    compressed, err := s.Compress([]byte{})
    assert.NoError(t, err)
    decompressed, err := s.Decompress(compressed)
    assert.NoError(t, err)
    assert.Empty(t, decompressed)
}

func TestSevenzDecompress_InvalidData(t *testing.T) {
    s := &Sevenz{}
    _, err := s.Decompress([]byte{0x00, 0x01, 0x02})
    assert.Error(t, err)
}

3. changes/dev.md 格式问题

修改后的文件格式不一致:

-  [[#130](...)] getty session auto close bug
+ - [[#130](...)] getty session auto close bug

总体评价:修复正确有效,建议明确命名与实际实现的关系。

@thunguo thunguo closed this Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working coding documentation Improvements or additions to documentation enhancement New feature or request milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] CompressorSevenz type registered but not implemented, silently falls back to NoneCompressor

5 participants