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

randombit / botan / 20579846577

29 Dec 2025 06:24PM UTC coverage: 90.415% (+0.2%) from 90.243%
20579846577

push

github

web-flow
Merge pull request #5167 from randombit/jack/src-size-reductions

Changes to reduce unnecessary inclusions

101523 of 112285 relevant lines covered (90.42%)

12817276.56 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
   #include <cstring>
13
#endif
14

15
namespace Botan_Tests {
16

17
#if defined(BOTAN_HAS_COMPRESSION)
18

19
namespace {
20

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

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

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

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

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

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

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

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

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

67
               result.start_timer();
5✔
68

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

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

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

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

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

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

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

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

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

113
               result.end_timer();
5✔
114

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

121
         return results;
1✔
122
      }
×
123

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

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

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

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

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

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

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

157
               decompressed += final_outputs;
100✔
158

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

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

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

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

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

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

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

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

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

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

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

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

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

221
}  // namespace
222

223
#endif
224

225
}  // 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