diff --git a/ChangeLog b/ChangeLog index 9e9fe223..e675e251 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-08-24 Tatsuhiro Tsujikawa + + Save temporary file first and rename to the destination on success. + Added test cases. + * src/RequestGroupMan.cc + * test/RequestGroupManTest.cc + 2008-08-23 Tatsuhiro Tsujikawa Fixed the bug that the number of connected peer is exceeding the limit diff --git a/src/RequestGroupMan.cc b/src/RequestGroupMan.cc index a795192b..9cc4ce72 100644 --- a/src/RequestGroupMan.cc +++ b/src/RequestGroupMan.cc @@ -51,6 +51,7 @@ #include "InOrderURISelector.h" #include "Option.h" #include "prefs.h" +#include "File.h" #include #include #include @@ -498,13 +499,14 @@ bool RequestGroupMan::loadServerStat(const std::string& filename) bool RequestGroupMan::saveServerStat(const std::string& filename) const { - std::ofstream out(filename.c_str()); + std::string tempfile = filename+"__temp"; + std::ofstream out(tempfile.c_str()); if(!out) { _logger->error("Failed to open ServerStat file %s for write.", - filename.c_str()); + tempfile.c_str()); return false; } - if(_serverStatMan->save(out)) { + if(_serverStatMan->save(out) && File(tempfile).renameTo(filename)) { _logger->notice("ServerStat file %s saved successfully.", filename.c_str()); return true; } else { diff --git a/test/RequestGroupManTest.cc b/test/RequestGroupManTest.cc index 8d08f34b..99197334 100644 --- a/test/RequestGroupManTest.cc +++ b/test/RequestGroupManTest.cc @@ -7,6 +7,9 @@ #include "DownloadResult.h" #include "FileEntry.h" #include "ServerStatMan.h" +#include "ServerStat.h" +#include "File.h" +#include #include namespace aria2 { @@ -16,6 +19,8 @@ class RequestGroupManTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(RequestGroupManTest); CPPUNIT_TEST(testIsSameFileBeingDownloaded); CPPUNIT_TEST(testGetInitialCommands); + CPPUNIT_TEST(testLoadServerStat); + CPPUNIT_TEST(testSaveServerStat); CPPUNIT_TEST_SUITE_END(); private: @@ -28,6 +33,8 @@ public: void testIsSameFileBeingDownloaded(); void testGetInitialCommands(); + void testLoadServerStat(); + void testSaveServerStat(); }; @@ -69,4 +76,39 @@ void RequestGroupManTest::testGetInitialCommands() // TODO implement later } +void RequestGroupManTest::testSaveServerStat() +{ + Option option; + RequestGroupMan rm(std::deque >(), 0, &option); + SharedHandle ss_localhost(new ServerStat("localhost", "http")); + rm.addServerStat(ss_localhost); + File f("/tmp/aria2_RequestGroupManTest_testSaveServerStat"); + if(f.exists()) { + f.remove(); + } + CPPUNIT_ASSERT(rm.saveServerStat(f.getPath())); + CPPUNIT_ASSERT(f.isFile()); + + f.remove(); + CPPUNIT_ASSERT(f.mkdirs()); + CPPUNIT_ASSERT(!rm.saveServerStat(f.getPath())); +} + +void RequestGroupManTest::testLoadServerStat() +{ + File f("/tmp/aria2_RequestGroupManTest_testLoadServerStat"); + std::ofstream o(f.getPath().c_str()); + o << "host=localhost, protocol=http, dl_speed=0, last_updated=1219505257," + << "status=OK"; + o.close(); + + Option option; + RequestGroupMan rm(std::deque >(), 0, &option); + CPPUNIT_ASSERT(rm.loadServerStat(f.getPath())); + SharedHandle ss_localhost = rm.findServerStat("localhost", + "http"); + CPPUNIT_ASSERT(!ss_localhost.isNull()); + CPPUNIT_ASSERT_EQUAL(std::string("localhost"), ss_localhost->getHostname()); +} + } // namespace aria2