• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 20283898778

16 Dec 2025 09:52PM UTC coverage: 90.52% (+0.2%) from 90.36%
20283898778

Pull #5167

github

web-flow
Merge 795a38954 into 3d96b675e
Pull Request #5167: Changes to reduce unnecessary inclusions

101154 of 111748 relevant lines covered (90.52%)

12682929.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.32
/src/tests/test_compression.cpp
1
/*
2
* (C) 2015 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "tests.h"
8

9
#if defined(BOTAN_HAS_COMPRESSION)
10
   #include <botan/compression.h>
11
   #include <botan/rng.h>
12
#endif
13

14
namespace Botan_Tests {
15

16
#if defined(BOTAN_HAS_COMPRESSION)
17

18
namespace {
19

20
const char* const COMPRESSION_TEST_TEXT =
21
   "'Twas brillig, and the slithy toves"
22
   "Did gyre and gimble in the wabe:"
23
   "All mimsy were the borogoves,"
24
   "And the mome raths outgrabe."
25

26
   "'Beware the Jabberwock, my son!"
27
   "The jaws that bite, the claws that catch!"
28
   "Beware the Jubjub bird, and shun"
29
   "The frumious Bandersnatch!'"
30

31
   "He took his vorpal sword in hand;"
32
   "Long time the manxome foe he sought-"
33
   "So rested he by the Tumtum tree"
34
   "And stood awhile in thought."
35

36
   "And, as in uffish thought he stood,"
37
   "The Jabberwock, with eyes of flame,"
38
   "Came whiffling through the tulgey wood,"
39
   "And burbled as it came!"
40

41
   "One, two! One, two! And through and through"
42
   "The vorpal blade went snicker-snack!"
43
   "He left it dead, and with its head"
44
   "He went galumphing back."
45

46
   "'And hast thou slain the Jabberwock?"
47
   "Come to my arms, my beamish boy!"
48
   "O frabjous day! Callooh! Callay!'"
49
   "He chortled in his joy."
50

51
   "'Twas brillig, and the slithy toves"
52
   "Did gyre and gimble in the wabe:"
53
   "All mimsy were the borogoves,"
54
   "And the mome raths outgrabe.";
55

56
class Compression_Tests final : public Test {
1✔
57
   public:
58
      std::vector<Test::Result> run() override {
1✔
59
         std::vector<Test::Result> results;
1✔
60
         const size_t text_len = std::strlen(COMPRESSION_TEST_TEXT);
1✔
61

62
         for(const std::string algo : {"zlib", "deflate", "gzip", "bz2", "lzma"}) {
6✔
63
            try {
5✔
64
               Test::Result result(algo + " compression");
5✔
65

66
               result.start_timer();
5✔
67

68
               auto c = Botan::Compression_Algorithm::create(algo);
5✔
69
               auto d = Botan::Decompression_Algorithm::create(algo);
5✔
70

71
               if(!c || !d) {
5✔
72
                  result.note_missing(algo);
×
73
                  continue;
×
74
               }
75

76
               result.test_ne("Not the same name", c->name(), d->name());
10✔
77

78
               const Botan::secure_vector<uint8_t> empty;
5✔
79
               const Botan::secure_vector<uint8_t> all_zeros(text_len, 0);
5✔
80
               const Botan::secure_vector<uint8_t> random_binary = this->rng().random_vec(text_len);
5✔
81
               const Botan::secure_vector<uint8_t> short_text = {'f', 'o', 'o', '\n'};
5✔
82

83
               const uint8_t* textb = reinterpret_cast<const uint8_t*>(COMPRESSION_TEST_TEXT);
5✔
84
               const Botan::secure_vector<uint8_t> text(textb, textb + text_len);
5✔
85

86
               const size_t c1_e = run_compression(result, 1, *c, *d, empty);
5✔
87
               const size_t c9_e = run_compression(result, 9, *c, *d, empty);
5✔
88
               const size_t c1_z = run_compression(result, 1, *c, *d, all_zeros);
5✔
89
               const size_t c9_z = run_compression(result, 9, *c, *d, all_zeros);
5✔
90
               const size_t c1_r = run_compression(result, 1, *c, *d, random_binary);
5✔
91
               const size_t c9_r = run_compression(result, 9, *c, *d, random_binary);
5✔
92
               const size_t c1_t = run_compression(result, 1, *c, *d, text);
5✔
93
               const size_t c9_t = run_compression(result, 9, *c, *d, text);
5✔
94
               const size_t c1_s = run_compression(result, 1, *c, *d, short_text);
5✔
95
               const size_t c9_s = run_compression(result, 9, *c, *d, short_text);
5✔
96

97
               result.test_gte("Empty input L1 compresses to non-empty output", c1_e, 1);
5✔
98
               result.test_gte("Empty input L9 compresses to non-empty output", c9_e, 1);
5✔
99

100
               // We assume that Level 9 is better than Level 1, but this is not
101
               // guaranteed (see GitHub #3896). Hence, we assert that level 9
102
               // it is at most 10% worse than level 1.
103
               result.test_gte("Level 9 compresses empty at least as well as level 1", c1_e + (c1_e / 10), c9_e);
5✔
104
               result.test_gte("Level 9 compresses zeros at least as well as level 1", c1_z + (c1_z / 10), c9_z);
5✔
105
               result.test_gte("Level 9 compresses random at least as well as level 1", c1_r + (c1_r / 10), c9_r);
5✔
106
               result.test_gte("Level 9 compresses text at least as well as level 1", c1_t + (c1_t / 10), c9_t);
5✔
107
               result.test_gte("Level 9 compresses short text at least as well as level 1", c1_s + (c1_s / 10), c9_s);
5✔
108

109
               result.test_lt("Zeros compresses much better than text", c1_z / 8, c1_t);
5✔
110
               result.test_lt("Text compresses much better than random", c1_t / 2, c1_r);
5✔
111

112
               result.end_timer();
5✔
113

114
               results.emplace_back(result);
5✔
115
            } catch(std::exception& e) {
30✔
116
               results.emplace_back(Test::Result::Failure("testing " + algo, e.what()));
×
117
            }
×
118
         }
5✔
119

120
         return results;
1✔
121
      }
×
122

123
   private:
124
      // Returns # of bytes of compressed message
125
      size_t run_compression(Test::Result& result,
50✔
126
                             size_t level,
127
                             Botan::Compression_Algorithm& c,
128
                             Botan::Decompression_Algorithm& d,
129
                             const Botan::secure_vector<uint8_t>& msg) {
130
         Botan::secure_vector<uint8_t> compressed(2 * msg.size());
50✔
131

132
         for(const bool with_flush : {true, false}) {
150✔
133
            try {
100✔
134
               compressed = msg;
100✔
135

136
               c.start(level);
100✔
137
               c.update(compressed, 0, false);
100✔
138

139
               if(with_flush) {
100✔
140
                  Botan::secure_vector<uint8_t> flush_bits;
50✔
141
                  c.update(flush_bits, 0, true);
50✔
142
                  compressed += flush_bits;
50✔
143
               }
50✔
144

145
               Botan::secure_vector<uint8_t> final_bits;
100✔
146
               c.finish(final_bits);
100✔
147
               compressed += final_bits;
100✔
148

149
               Botan::secure_vector<uint8_t> decompressed = compressed;
100✔
150
               d.start();
100✔
151
               d.update(decompressed);
100✔
152

153
               Botan::secure_vector<uint8_t> final_outputs;
100✔
154
               d.finish(final_outputs);
100✔
155

156
               decompressed += final_outputs;
100✔
157

158
               result.test_eq("compression round tripped", msg, decompressed);
200✔
159
            } catch(Botan::Exception& e) {
300✔
160
               result.test_failure(e.what());
×
161
            }
×
162
         }
163

164
         return compressed.size();
50✔
165
      }
50✔
166
};
167

168
BOTAN_REGISTER_TEST("compression", "compression_tests", Compression_Tests);
169

170
class CompressionCreate_Tests final : public Test {
1✔
171
   public:
172
      std::vector<Test::Result> run() override {
1✔
173
         std::vector<Test::Result> results;
1✔
174

175
         for(const std::string algo : {"zlib", "deflate", "gzip", "bz2", "lzma"}) {
6✔
176
            try {
5✔
177
               Test::Result result(algo + " create compression");
5✔
178

179
               auto c1 = Botan::Compression_Algorithm::create(algo);
5✔
180
               auto d1 = Botan::Decompression_Algorithm::create(algo);
5✔
181

182
               if(!c1 || !d1) {
5✔
183
                  result.note_missing(algo);
×
184
                  continue;
×
185
               }
186
               result.test_ne("Not the same name after create", c1->name(), d1->name());
10✔
187

188
               auto c2 = Botan::Compression_Algorithm::create_or_throw(algo);
5✔
189
               auto d2 = Botan::Decompression_Algorithm::create_or_throw(algo);
5✔
190

191
               if(!c2 || !d2) {
5✔
192
                  result.note_missing(algo);
×
193
                  continue;
×
194
               }
195
               result.test_ne("Not the same name after create_or_throw", c2->name(), d2->name());
10✔
196

197
               results.emplace_back(result);
5✔
198
            } catch(std::exception& e) {
20✔
199
               results.emplace_back(Test::Result::Failure("testing " + algo, e.what()));
×
200
            }
×
201
         }
5✔
202

203
         {
1✔
204
            Test::Result result("create invalid compression");
1✔
205
            result.test_throws("lookup error", "Unavailable Compression bogocompress", [&]() {
2✔
206
               Botan::Compression_Algorithm::create_or_throw("bogocompress");
1✔
207
            });
×
208
            result.test_throws("lookup error", "Unavailable Decompression bogocompress", [&]() {
2✔
209
               Botan::Decompression_Algorithm::create_or_throw("bogocompress");
1✔
210
            });
×
211
            results.emplace_back(result);
1✔
212
         }
1✔
213

214
         return results;
1✔
215
      }
×
216
};
217

218
BOTAN_REGISTER_TEST("compression", "create_compression", CompressionCreate_Tests);
219

220
}  // namespace
221

222
#endif
223

224
}  // namespace Botan_Tests
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc