mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-05 09:33:25 -08:00
[Tests] Run the short-write cases without forking a death test
The three cases that force a write failure - CardDatabaseTest.Xml4ShortWriteKeepsInstalledFile, OracleDatabaseWriter.ShortWriteKeepsPreviouslyInstalledDatabase and SpoilerFileTest.ShortWriteLeavesExistingFileIntact - all forked a child, lowered RLIMIT_FSIZE and ignored SIGXFSZ. That child is killed by SIGSEGV on the macOS runners, so all three have been red on every macOS leg of master since they landed, while the same cases pass on Linux. Cap the soft limit in the test process instead: ctest already runs one case per process, and the guard restores the limit and the SIGXFSZ handler, so a whole binary keeps working. Same real EFBIG failure, no fork, and macOS keeps its coverage of the writers.
This commit is contained in:
parent
82b74ce594
commit
dc83a7cab1
4 changed files with 112 additions and 64 deletions
|
|
@ -1,4 +1,5 @@
|
|||
#include "client/network/update/card_spoiler/spoiler_file.h"
|
||||
#include "support/scoped_file_size_limit.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
|
|
@ -6,12 +7,6 @@
|
|||
#include <QTemporaryDir>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <csignal>
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
class SpoilerFileTest : public ::testing::Test
|
||||
|
|
@ -123,25 +118,16 @@ TEST_F(SpoilerFileTest, FileInParentPathReportsFailureWithoutModifyingIt)
|
|||
#ifdef Q_OS_UNIX
|
||||
TEST_F(SpoilerFileTest, ShortWriteLeavesExistingFileIntact)
|
||||
{
|
||||
// Limit only the child process: a real short write exercises QSaveFile's
|
||||
// buffered flush failure without depending on disk capacity or file ownership.
|
||||
const QByteArray changed = "<cockatrice_carddatabase version=\"4\"><!--" + QByteArray(100000, 'x') +
|
||||
"--><cards/></cockatrice_carddatabase>";
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
struct rlimit limit;
|
||||
if (getrlimit(RLIMIT_FSIZE, &limit) != 0) {
|
||||
_exit(2);
|
||||
}
|
||||
limit.rlim_cur = 128;
|
||||
if (setrlimit(RLIMIT_FSIZE, &limit) != 0) {
|
||||
_exit(3);
|
||||
}
|
||||
std::signal(SIGXFSZ, SIG_IGN);
|
||||
const auto result = save(changed);
|
||||
_exit(result == SpoilerFile::SaveResult::Failed && !error.isEmpty() ? 0 : 1);
|
||||
},
|
||||
::testing::ExitedWithCode(0), "");
|
||||
// A real short write exercises QSaveFile's buffered flush failure without depending
|
||||
// on disk capacity. The cap is scoped rather than forked, because a death-test child
|
||||
// under RLIMIT_FSIZE is killed by SIGSEGV on macOS.
|
||||
test_support::ScopedFileSizeLimit fileSizeCap(128);
|
||||
ASSERT_TRUE(fileSizeCap.isValid());
|
||||
|
||||
EXPECT_EQ(save(changed), SpoilerFile::SaveResult::Failed);
|
||||
EXPECT_FALSE(error.isEmpty());
|
||||
EXPECT_EQ(read(), original);
|
||||
EXPECT_EQ(QDir(directory.path()).entryList(QDir::Files), QStringList{"spoiler.xml"});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue