1// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package lzma 6 7import ( 8 "bytes" 9 "io" 10 "io/ioutil" 11 "math/rand" 12 "testing" 13 14 "github.com/ulikunitz/xz/internal/randtxt" 15) 16 17var testString = `LZMA decoder test example 18========================= 19! LZMA ! Decoder ! TEST ! 20========================= 21! TEST ! LZMA ! Decoder ! 22========================= 23---- Test Line 1 -------- 24========================= 25---- Test Line 2 -------- 26========================= 27=== End of test file ==== 28========================= 29` 30 31func cycle(t *testing.T, n int) { 32 t.Logf("cycle(t,%d)", n) 33 if n > len(testString) { 34 t.Fatalf("cycle: n=%d larger than len(testString)=%d", n, 35 len(testString)) 36 } 37 const dictCap = MinDictCap 38 m, err := newHashTable(dictCap, 4) 39 if err != nil { 40 t.Fatal(err) 41 } 42 encoderDict, err := newEncoderDict(dictCap, dictCap+1024, m) 43 if err != nil { 44 t.Fatal(err) 45 } 46 props := Properties{2, 0, 2} 47 if err := props.verify(); err != nil { 48 t.Fatalf("properties error %s", err) 49 } 50 state := newState(props) 51 var buf bytes.Buffer 52 w, err := newEncoder(&buf, state, encoderDict, eosMarker) 53 if err != nil { 54 t.Fatalf("newEncoder error %s", err) 55 } 56 orig := []byte(testString)[:n] 57 t.Logf("len(orig) %d", len(orig)) 58 k, err := w.Write(orig) 59 if err != nil { 60 t.Fatalf("w.Write error %s", err) 61 } 62 if k != len(orig) { 63 t.Fatalf("w.Write returned %d; want %d", k, len(orig)) 64 } 65 if err = w.Close(); err != nil { 66 t.Fatalf("w.Close error %s", err) 67 } 68 t.Logf("buf.Len() %d len(orig) %d", buf.Len(), len(orig)) 69 decoderDict, err := newDecoderDict(dictCap) 70 if err != nil { 71 t.Fatalf("newDecoderDict error %s", err) 72 } 73 state.Reset() 74 r, err := newDecoder(&buf, state, decoderDict, -1) 75 if err != nil { 76 t.Fatalf("newDecoder error %s", err) 77 } 78 decoded, err := ioutil.ReadAll(r) 79 if err != nil { 80 t.Fatalf("ReadAll(lr) error %s", err) 81 } 82 t.Logf("decoded: %s", decoded) 83 if len(orig) != len(decoded) { 84 t.Fatalf("length decoded is %d; want %d", len(decoded), 85 len(orig)) 86 } 87 if !bytes.Equal(orig, decoded) { 88 t.Fatalf("decoded file differs from original") 89 } 90} 91 92func TestEncoderCycle1(t *testing.T) { 93 cycle(t, len(testString)) 94} 95 96func TestEncoderCycle2(t *testing.T) { 97 buf := new(bytes.Buffer) 98 const txtlen = 50000 99 io.CopyN(buf, randtxt.NewReader(rand.NewSource(42)), txtlen) 100 txt := buf.String() 101 buf.Reset() 102 const dictCap = MinDictCap 103 m, err := newHashTable(dictCap, 4) 104 if err != nil { 105 t.Fatal(err) 106 } 107 encoderDict, err := newEncoderDict(dictCap, dictCap+1024, m) 108 if err != nil { 109 t.Fatal(err) 110 } 111 props := Properties{3, 0, 2} 112 if err := props.verify(); err != nil { 113 t.Fatalf("properties error %s", err) 114 } 115 state := newState(props) 116 lbw := &LimitedByteWriter{BW: buf, N: 100} 117 w, err := newEncoder(lbw, state, encoderDict, 0) 118 if err != nil { 119 t.Fatalf("NewEncoder error %s", err) 120 } 121 _, err = io.WriteString(w, txt) 122 if err != nil && err != ErrLimit { 123 t.Fatalf("WriteString error %s", err) 124 } 125 if err = w.Close(); err != nil { 126 t.Fatalf("w.Close error %s", err) 127 } 128 n := w.Compressed() 129 txt = txt[:n] 130 decoderDict, err := newDecoderDict(dictCap) 131 if err != nil { 132 t.Fatalf("NewDecoderDict error %s", err) 133 } 134 state.Reset() 135 r, err := newDecoder(buf, state, decoderDict, n) 136 if err != nil { 137 t.Fatalf("NewDecoder error %s", err) 138 } 139 out := new(bytes.Buffer) 140 if _, err = io.Copy(out, r); err != nil { 141 t.Fatalf("decompress copy error %s", err) 142 } 143 got := out.String() 144 t.Logf("%s", got) 145 if len(got) != int(n) { 146 t.Fatalf("len(got) %d; want %d", len(got), n) 147 } 148 if got != txt { 149 t.Fatalf("got and txt differ") 150 } 151} 152