@@ -149,6 +149,68 @@ func TestNewDecoder(t *testing.T) {
149149 testDecoderDecodeAll (t , "testdata/decoder.zip" , dec )
150150}
151151
152+ func TestNewDecoderMemory (t * testing.T ) {
153+ defer timeout (60 * time .Second )()
154+ var testdata bytes.Buffer
155+ enc , err := NewWriter (& testdata , WithWindowSize (64 << 10 ), WithSingleSegment (false ))
156+ if err != nil {
157+ t .Fatal (err )
158+ }
159+ // Write 256KB
160+ for i := 0 ; i < 256 ; i ++ {
161+ tmp := strings .Repeat (string ([]byte {byte (i )}), 1024 )
162+ _ , err := enc .Write ([]byte (tmp ))
163+ if err != nil {
164+ t .Fatal (err )
165+ }
166+ }
167+ err = enc .Close ()
168+ if err != nil {
169+ t .Fatal (err )
170+ }
171+
172+ var n = 5000
173+ if testing .Short () {
174+ n = 200
175+ }
176+
177+ var before , after runtime.MemStats
178+ runtime .GC ()
179+ runtime .ReadMemStats (& before )
180+
181+ var decs = make ([]* Decoder , n )
182+ for i := range decs {
183+ // Wrap in NopCloser to avoid shortcut.
184+ input := ioutil .NopCloser (bytes .NewBuffer (testdata .Bytes ()))
185+ decs [i ], err = NewReader (input , WithDecoderConcurrency (1 ), WithDecoderLowmem (true ))
186+ if err != nil {
187+ t .Fatal (err )
188+ }
189+ }
190+
191+ // 32K buffer
192+ var tmp [128 << 10 ]byte
193+ for i := range decs {
194+ _ , err := io .ReadFull (decs [i ], tmp [:])
195+ if err != nil {
196+ t .Fatal (err )
197+ }
198+ }
199+
200+ runtime .GC ()
201+ runtime .ReadMemStats (& after )
202+ size := (after .HeapInuse - before .HeapInuse ) / uint64 (n ) / 1024
203+ t .Log (size , "KiB per decoder" )
204+ // This is not exact science, but fail if we suddenly get more than 2x what we expect.
205+ if size > 221 * 2 && ! testing .Short () {
206+ t .Errorf ("expected < 221KB per decoder, got %d" , size )
207+ }
208+
209+ for _ , dec := range decs {
210+ dec .Close ()
211+ }
212+ }
213+
152214func TestNewDecoderGood (t * testing.T ) {
153215 defer timeout (30 * time .Second )()
154216 testDecoderFile (t , "testdata/good.zip" )
0 commit comments