Merge pull request #365 from kiwix/server_corner_cases_unit_test

This commit is contained in:
Matthieu Gautier 2020-06-08 15:28:59 +02:00 committed by GitHub
commit fd62acd232
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 54 additions and 7 deletions

BIN
test/data/corner_cases.zim Normal file

Binary file not shown.

View File

View File

View File

View File

View File

@ -0,0 +1,15 @@
#!/usr/bin/env bash
cd "$(dirname "$0")"
rm -f corner_cases.zim
zimwriterfs -w empty.html \
-f empty.png \
-l=en \
-t="ZIM corner cases" \
-d="" \
-c="" \
-p="" \
corner_cases \
corner_cases.zim \
&& echo 'corner_cases.zim was successfully created' \
|| echo '!!! Failed to create corner_cases.zim !!!' >&2

View File

@ -29,6 +29,9 @@ if gtest_dep.found() and not meson.is_cross_build()
configure_file(input : 'data/wikipedia_en_ray_charles_mini_2020-03.zim', configure_file(input : 'data/wikipedia_en_ray_charles_mini_2020-03.zim',
output : 'zimfile.zim', output : 'zimfile.zim',
copy: true ) copy: true )
configure_file(input : 'data/corner_cases.zim',
output : 'corner_cases.zim',
copy: true )
foreach test_name : tests foreach test_name : tests
# XXX: implicit_include_directories must be set to false, otherwise # XXX: implicit_include_directories must be set to false, otherwise

View File

@ -50,9 +50,10 @@ class ZimFileServer
{ {
public: // types public: // types
typedef std::shared_ptr<httplib::Response> Response; typedef std::shared_ptr<httplib::Response> Response;
typedef std::vector<std::string> FilePathCollection;
public: // functions public: // functions
ZimFileServer(int serverPort, std::string zimpath); ZimFileServer(int serverPort, const FilePathCollection& zimpaths);
~ZimFileServer(); ~ZimFileServer();
Response GET(const char* path, const Headers& headers = Headers()) Response GET(const char* path, const Headers& headers = Headers())
@ -73,11 +74,13 @@ private: // data
std::unique_ptr<httplib::Client> client; std::unique_ptr<httplib::Client> client;
}; };
ZimFileServer::ZimFileServer(int serverPort, std::string zimpath) ZimFileServer::ZimFileServer(int serverPort, const FilePathCollection& zimpaths)
: manager(&this->library) : manager(&this->library)
{ {
for ( const auto zimpath : zimpaths ) {
if (!manager.addBookFromPath(zimpath, zimpath, "", false)) if (!manager.addBookFromPath(zimpath, zimpath, "", false))
throw std::runtime_error("Unable to add the ZIM file '" + zimpath + "'"); throw std::runtime_error("Unable to add the ZIM file '" + zimpath + "'");
}
const std::string address = "127.0.0.1"; const std::string address = "127.0.0.1";
nameMapper.reset(new kiwix::HumanReadableNameMapper(library, false)); nameMapper.reset(new kiwix::HumanReadableNameMapper(library, false));
@ -104,11 +107,14 @@ protected:
std::unique_ptr<ZimFileServer> zfs1_; std::unique_ptr<ZimFileServer> zfs1_;
const int PORT = 8001; const int PORT = 8001;
const std::string ZIMFILE = "./test/zimfile.zim"; const ZimFileServer::FilePathCollection ZIMFILES {
"./test/zimfile.zim",
"./test/corner_cases.zim"
};
protected: protected:
void SetUp() override { void SetUp() override {
zfs1_.reset(new ZimFileServer(PORT, ZIMFILE)); zfs1_.reset(new ZimFileServer(PORT, ZIMFILES));
} }
void TearDown() override { void TearDown() override {
@ -174,6 +180,10 @@ const ResourceCollection resources200Uncompressible{
{ WITH_ETAG, "/meta?content=zimfile&name=favicon" }, { WITH_ETAG, "/meta?content=zimfile&name=favicon" },
{ WITH_ETAG, "/zimfile/I/m/Ray_Charles_classic_piano_pose.jpg" }, { WITH_ETAG, "/zimfile/I/m/Ray_Charles_classic_piano_pose.jpg" },
{ WITH_ETAG, "/corner_cases/A/empty.html" },
{ WITH_ETAG, "/corner_cases/-/empty.css" },
{ WITH_ETAG, "/corner_cases/-/empty.js" },
}; };
ResourceCollection all200Resources() ResourceCollection all200Resources()
@ -307,7 +317,7 @@ TEST_F(ServerTest, ETagIsTheSameAcrossHeadAndGet)
TEST_F(ServerTest, DifferentServerInstancesProduceDifferentETags) TEST_F(ServerTest, DifferentServerInstancesProduceDifferentETags)
{ {
ZimFileServer zfs2(PORT + 1, ZIMFILE); ZimFileServer zfs2(PORT + 1, ZIMFILES);
for ( const Resource& res : all200Resources() ) { for ( const Resource& res : all200Resources() ) {
if ( !res.etag_expected ) continue; if ( !res.etag_expected ) continue;
const auto h1 = zfs1_->HEAD(res.url); const auto h1 = zfs1_->HEAD(res.url);
@ -480,6 +490,25 @@ TEST_F(ServerTest, InvalidAndMultiRangeByteRangeRequestsResultIn416Responses)
} }
} }
TEST_F(ServerTest, ValidByteRangeRequestsOfZeroSizedEntriesResultIn416Responses)
{
const char url[] = "/corner_cases/-/empty.js";
const char* ranges[] = {
"bytes=0-",
"bytes=-100"
};
for( const char* range : ranges )
{
const TestContext ctx{ {"Range", range} };
const auto p = zfs1_->GET(url, { {"Range", range } } );
EXPECT_EQ(416, p->status) << ctx;
EXPECT_TRUE(p->body.empty()) << ctx;
EXPECT_EQ("bytes */0", p->get_header_value("Content-Range")) << ctx;
}
}
TEST_F(ServerTest, RangeHasPrecedenceOverCompression) TEST_F(ServerTest, RangeHasPrecedenceOverCompression)
{ {
const char url[] = "/zimfile/I/m/Ray_Charles_classic_piano_pose.jpg"; const char url[] = "/zimfile/I/m/Ray_Charles_classic_piano_pose.jpg";