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

randombit / botan / 5111374265

29 May 2023 11:19AM UTC coverage: 92.227% (+0.5%) from 91.723%
5111374265

push

github

randombit
Next release will be 3.1.0. Update release notes

75588 of 81959 relevant lines covered (92.23%)

11886470.91 hits per line

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

88.35
/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
#endif
12

13
namespace Botan_Tests {
14

15
#if defined(BOTAN_HAS_COMPRESSION)
16

17
namespace {
18

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

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

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

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

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

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

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

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

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

65
               result.start_timer();
5✔
66

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

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

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

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

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

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

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

99
               result.test_gte("Level 9 compresses empty at least as well as level 1", c1_e, c9_e);
5✔
100
               result.test_gte("Level 9 compresses zeros at least as well as level 1", c1_z, c9_z);
5✔
101
               result.test_gte("Level 9 compresses random at least as well as level 1", c1_r, c9_r);
5✔
102
               result.test_gte("Level 9 compresses text at least as well as level 1", c1_t, c9_t);
5✔
103
               result.test_gte("Level 9 compresses short text at least as well as level 1", c1_s, c9_s);
5✔
104

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

108
               result.end_timer();
5✔
109

110
               results.emplace_back(result);
5✔
111
            } catch(std::exception& e) { results.emplace_back(Test::Result::Failure("testing " + algo, e.what())); }
30✔
112
         }
5✔
113

114
         return results;
1✔
115
      }
×
116

117
   private:
118
      // Returns # of bytes of compressed message
119
      size_t run_compression(Test::Result& result,
50✔
120
                             size_t level,
121
                             Botan::Compression_Algorithm& c,
122
                             Botan::Decompression_Algorithm& d,
123
                             const Botan::secure_vector<uint8_t>& msg) {
124
         Botan::secure_vector<uint8_t> compressed(2 * msg.size());
50✔
125

126
         for(bool with_flush : {true, false}) {
150✔
127
            try {
100✔
128
               compressed = msg;
100✔
129

130
               c.start(level);
100✔
131
               c.update(compressed, 0, false);
100✔
132

133
               if(with_flush) {
100✔
134
                  Botan::secure_vector<uint8_t> flush_bits;
50✔
135
                  c.update(flush_bits, 0, true);
50✔
136
                  compressed += flush_bits;
50✔
137
               }
50✔
138

139
               Botan::secure_vector<uint8_t> final_bits;
100✔
140
               c.finish(final_bits);
100✔
141
               compressed += final_bits;
100✔
142

143
               Botan::secure_vector<uint8_t> decompressed = compressed;
100✔
144
               d.start();
100✔
145
               d.update(decompressed);
100✔
146

147
               Botan::secure_vector<uint8_t> final_outputs;
100✔
148
               d.finish(final_outputs);
100✔
149

150
               decompressed += final_outputs;
100✔
151

152
               result.test_eq("compression round tripped", msg, decompressed);
200✔
153
            } catch(Botan::Exception& e) { result.test_failure(e.what()); }
300✔
154
         }
155

156
         return compressed.size();
50✔
157
      }
50✔
158
};
159

160
BOTAN_REGISTER_TEST("compression", "compression_tests", Compression_Tests);
161

162
class CompressionCreate_Tests final : public Test {
×
163
   public:
164
      std::vector<Test::Result> run() override {
1✔
165
         std::vector<Test::Result> results;
1✔
166

167
         for(std::string algo : {"zlib", "deflate", "gzip", "bz2", "lzma"}) {
6✔
168
            try {
5✔
169
               Test::Result result(algo + " create compression");
5✔
170

171
               auto c1 = Botan::Compression_Algorithm::create(algo);
5✔
172
               auto d1 = Botan::Decompression_Algorithm::create(algo);
5✔
173

174
               if(!c1 || !d1) {
5✔
175
                  result.note_missing(algo);
×
176
                  continue;
×
177
               }
178
               result.test_ne("Not the same name after create", c1->name(), d1->name());
15✔
179

180
               auto c2 = Botan::Compression_Algorithm::create_or_throw(algo);
5✔
181
               auto d2 = Botan::Decompression_Algorithm::create_or_throw(algo);
5✔
182

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

189
               results.emplace_back(result);
5✔
190
            } catch(std::exception& e) { results.emplace_back(Test::Result::Failure("testing " + algo, e.what())); }
20✔
191
         }
5✔
192

193
         {
1✔
194
            Test::Result result("create invalid compression");
1✔
195
            result.test_throws("lookup error", "Unavailable Compression bogocompress", [&]() {
3✔
196
               Botan::Compression_Algorithm::create_or_throw("bogocompress");
1✔
197
            });
×
198
            result.test_throws("lookup error", "Unavailable Decompression bogocompress", [&]() {
3✔
199
               Botan::Decompression_Algorithm::create_or_throw("bogocompress");
1✔
200
            });
×
201
            results.emplace_back(result);
1✔
202
         }
1✔
203

204
         return results;
1✔
205
      }
×
206
};
207

208
BOTAN_REGISTER_TEST("compression", "create_compression", CompressionCreate_Tests);
209

210
}  // namespace
211

212
#endif
213

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

© 2025 Coveralls, Inc