e9e077a843
It currently fails there, so don't run it until this is fixed to let the tests pass globally. See #14480. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72080 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
842 lines
22 KiB
C++
842 lines
22 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: tests/fswatcher/fswatchertest.cpp
|
|
// Purpose: wxFileSystemWatcher unit test
|
|
// Author: Bartosz Bekier
|
|
// Created: 2009-06-11
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) 2009 Bartosz Bekier
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// headers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#include "testprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/timer.h"
|
|
#endif
|
|
|
|
#include "wx/evtloop.h"
|
|
#include "wx/filename.h"
|
|
#include "wx/filefn.h"
|
|
#include "wx/stdpaths.h"
|
|
#include "wx/fswatcher.h"
|
|
|
|
#include "testfile.h"
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// local functions
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// class generating file system events
|
|
class EventGenerator
|
|
{
|
|
public:
|
|
static EventGenerator& Get()
|
|
{
|
|
if (!ms_instance)
|
|
ms_instance = new EventGenerator(GetWatchDir());
|
|
|
|
return *ms_instance;
|
|
}
|
|
|
|
EventGenerator(const wxFileName& path) : m_base(path)
|
|
{
|
|
m_old = wxFileName();
|
|
m_file = RandomName();
|
|
m_new = RandomName();
|
|
}
|
|
|
|
// operations
|
|
bool CreateFile()
|
|
{
|
|
wxFile file(m_file.GetFullPath(), wxFile::write);
|
|
return file.IsOpened() && m_file.FileExists();
|
|
}
|
|
|
|
bool RenameFile()
|
|
{
|
|
CPPUNIT_ASSERT(m_file.FileExists());
|
|
|
|
wxLogDebug("Renaming %s=>%s", m_file.GetFullPath(), m_new.GetFullPath());
|
|
|
|
bool ret = wxRenameFile(m_file.GetFullPath(), m_new.GetFullPath());
|
|
if (ret)
|
|
{
|
|
m_old = m_file;
|
|
m_file = m_new;
|
|
m_new = RandomName();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool DeleteFile()
|
|
{
|
|
CPPUNIT_ASSERT(m_file.FileExists());
|
|
|
|
bool ret = wxRemoveFile(m_file.GetFullPath());
|
|
if (ret)
|
|
{
|
|
m_old = m_file;
|
|
m_file = m_new;
|
|
m_new = RandomName();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool TouchFile()
|
|
{
|
|
return m_file.Touch();
|
|
}
|
|
|
|
bool ReadFile()
|
|
{
|
|
wxFile f(m_file.GetFullPath());
|
|
CPPUNIT_ASSERT(f.IsOpened());
|
|
|
|
char buf[1];
|
|
ssize_t count = f.Read(buf, sizeof(buf));
|
|
CPPUNIT_ASSERT(count > 0);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ModifyFile()
|
|
{
|
|
CPPUNIT_ASSERT(m_file.FileExists());
|
|
|
|
wxFile file(m_file.GetFullPath(), wxFile::write_append);
|
|
CPPUNIT_ASSERT(file.IsOpened());
|
|
|
|
CPPUNIT_ASSERT(file.Write("Words of Wisdom, Lloyd. Words of wisdom\n"));
|
|
return file.Close();
|
|
}
|
|
|
|
// helpers
|
|
wxFileName RandomName(int length = 10)
|
|
{
|
|
return RandomName(m_base, length);
|
|
}
|
|
|
|
// static helpers
|
|
static const wxFileName& GetWatchDir()
|
|
{
|
|
static wxFileName dir;
|
|
|
|
if (dir.DirExists())
|
|
return dir;
|
|
|
|
wxString tmp = wxStandardPaths::Get().GetTempDir();
|
|
dir.AssignDir(tmp);
|
|
|
|
// XXX look for more unique name? there is no function to generate
|
|
// unique filename, the file always get created...
|
|
dir.AppendDir("fswatcher_test");
|
|
CPPUNIT_ASSERT(!dir.DirExists());
|
|
CPPUNIT_ASSERT(dir.Mkdir());
|
|
|
|
return dir;
|
|
}
|
|
|
|
static void RemoveWatchDir()
|
|
{
|
|
wxFileName dir = GetWatchDir();
|
|
CPPUNIT_ASSERT(dir.DirExists());
|
|
|
|
// just to be really sure we know what we remove
|
|
CPPUNIT_ASSERT_EQUAL( "fswatcher_test", dir.GetDirs().Last() );
|
|
|
|
// FIXME-VC6: using non-static Rmdir() results in ICE
|
|
CPPUNIT_ASSERT( wxFileName::Rmdir(dir.GetFullPath(), wxPATH_RMDIR_RECURSIVE) );
|
|
}
|
|
|
|
static wxFileName RandomName(const wxFileName& base, int length = 10)
|
|
{
|
|
static int ALFA_CNT = 'z' - 'a';
|
|
|
|
wxString s;
|
|
for (int i = 0 ; i < length; ++i)
|
|
{
|
|
char c = 'a' + (rand() % ALFA_CNT);
|
|
s += c;
|
|
}
|
|
|
|
return wxFileName(base.GetFullPath(), s);
|
|
}
|
|
|
|
public:
|
|
wxFileName m_base; // base dir for doing operations
|
|
wxFileName m_file; // current file name
|
|
wxFileName m_old; // previous file name
|
|
wxFileName m_new; // name after renaming
|
|
|
|
protected:
|
|
static EventGenerator* ms_instance;
|
|
};
|
|
|
|
EventGenerator* EventGenerator::ms_instance = 0;
|
|
|
|
|
|
// custom event handler
|
|
class EventHandler : public wxEvtHandler
|
|
{
|
|
public:
|
|
enum { WAIT_DURATION = 3 };
|
|
|
|
EventHandler() :
|
|
eg(EventGenerator::Get()), m_loop(0), m_count(0), m_watcher(0)
|
|
{
|
|
m_loop = new wxEventLoop();
|
|
Connect(wxEVT_IDLE, wxIdleEventHandler(EventHandler::OnIdle));
|
|
Connect(wxEVT_FSWATCHER, wxFileSystemWatcherEventHandler(
|
|
EventHandler::OnFileSystemEvent));
|
|
}
|
|
|
|
virtual ~EventHandler()
|
|
{
|
|
delete m_watcher;
|
|
if (m_loop)
|
|
{
|
|
if (m_loop->IsRunning())
|
|
m_loop->Exit();
|
|
delete m_loop;
|
|
}
|
|
}
|
|
|
|
void Exit()
|
|
{
|
|
m_loop->Exit();
|
|
}
|
|
|
|
// sends idle event, so we get called in a moment
|
|
void SendIdle()
|
|
{
|
|
wxIdleEvent* e = new wxIdleEvent();
|
|
QueueEvent(e);
|
|
}
|
|
|
|
void Run()
|
|
{
|
|
SendIdle();
|
|
m_loop->Run();
|
|
}
|
|
|
|
void OnIdle(wxIdleEvent& /*evt*/)
|
|
{
|
|
bool more = Action();
|
|
m_count++;
|
|
|
|
if (more)
|
|
{
|
|
SendIdle();
|
|
}
|
|
}
|
|
|
|
// returns whether we should produce more idle events
|
|
virtual bool Action()
|
|
{
|
|
switch (m_count)
|
|
{
|
|
case 0:
|
|
CPPUNIT_ASSERT(Init());
|
|
break;
|
|
case 1:
|
|
GenerateEvent();
|
|
break;
|
|
case 2:
|
|
// actual test
|
|
CheckResult();
|
|
Exit();
|
|
break;
|
|
|
|
// TODO a mechanism that will break the loop in case we
|
|
// don't receive a file system event
|
|
// this below doesn't quite work, so all tests must pass :-)
|
|
#if 0
|
|
case 2:
|
|
m_loop.Yield();
|
|
m_loop.WakeUp();
|
|
CPPUNIT_ASSERT(KeepWaiting());
|
|
m_loop.Yield();
|
|
break;
|
|
case 3:
|
|
break;
|
|
case 4:
|
|
CPPUNIT_ASSERT(AfterWait());
|
|
break;
|
|
#endif
|
|
} // switch (m_count)
|
|
|
|
return m_count <= 0;
|
|
}
|
|
|
|
virtual bool Init()
|
|
{
|
|
// test we're good to go
|
|
CPPUNIT_ASSERT(wxEventLoopBase::GetActive());
|
|
|
|
// XXX only now can we construct Watcher, because we need
|
|
// active loop here
|
|
m_watcher = new wxFileSystemWatcher();
|
|
m_watcher->SetOwner(this);
|
|
|
|
// add dir to be watched
|
|
wxFileName dir = EventGenerator::GetWatchDir();
|
|
CPPUNIT_ASSERT(m_watcher->Add(dir, wxFSW_EVENT_ALL));
|
|
|
|
return true;
|
|
}
|
|
|
|
virtual bool KeepWaiting()
|
|
{
|
|
// did we receive event already?
|
|
if (!tested)
|
|
{
|
|
// well, let's wait a bit more
|
|
wxSleep(WAIT_DURATION);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
virtual bool AfterWait()
|
|
{
|
|
// fail if still no events
|
|
WX_ASSERT_MESSAGE
|
|
(
|
|
("No events during %d seconds!", static_cast<int>(WAIT_DURATION)),
|
|
tested
|
|
);
|
|
|
|
return true;
|
|
}
|
|
|
|
virtual void OnFileSystemEvent(wxFileSystemWatcherEvent& evt)
|
|
{
|
|
wxLogDebug("--- %s ---", evt.ToString());
|
|
m_lastEvent = wxDynamicCast(evt.Clone(), wxFileSystemWatcherEvent);
|
|
m_events.Add(m_lastEvent);
|
|
|
|
// test finished
|
|
SendIdle();
|
|
tested = true;
|
|
}
|
|
|
|
virtual void CheckResult()
|
|
{
|
|
CPPUNIT_ASSERT_MESSAGE( "No events received", !m_events.empty() );
|
|
|
|
const wxFileSystemWatcherEvent * const e = m_events.front();
|
|
|
|
// this is our "reference event"
|
|
const wxFileSystemWatcherEvent expected = ExpectedEvent();
|
|
|
|
CPPUNIT_ASSERT_EQUAL( expected.GetChangeType(), e->GetChangeType() );
|
|
|
|
CPPUNIT_ASSERT_EQUAL((int)wxEVT_FSWATCHER, e->GetEventType());
|
|
|
|
// XXX this needs change
|
|
CPPUNIT_ASSERT_EQUAL(wxEVT_CATEGORY_UNKNOWN, e->GetEventCategory());
|
|
|
|
CPPUNIT_ASSERT_EQUAL(expected.GetPath(), e->GetPath());
|
|
CPPUNIT_ASSERT_EQUAL(expected.GetNewPath(), e->GetNewPath());
|
|
|
|
// Under MSW extra modification events are sometimes reported after a
|
|
// rename and we just can't get rid of them, so ignore them in this
|
|
// test if they do happen.
|
|
if ( e->GetChangeType() == wxFSW_EVENT_RENAME &&
|
|
m_events.size() == 2 )
|
|
{
|
|
const wxFileSystemWatcherEvent* const e2 = m_events.back();
|
|
if ( e2->GetChangeType() == wxFSW_EVENT_MODIFY &&
|
|
e2->GetPath() == e->GetNewPath() )
|
|
{
|
|
// This is a modify event for the new file, ignore it.
|
|
return;
|
|
}
|
|
}
|
|
|
|
WX_ASSERT_EQUAL_MESSAGE
|
|
(
|
|
(
|
|
"Extra events received, last one is of type %x, path=\"%s\" "
|
|
"(the original event was for \"%s\" (\"%s\")",
|
|
m_events.back()->GetChangeType(),
|
|
m_events.back()->GetPath().GetFullPath(),
|
|
e->GetPath().GetFullPath(),
|
|
e->GetNewPath().GetFullPath()
|
|
),
|
|
1, m_events.size()
|
|
);
|
|
|
|
}
|
|
|
|
virtual void GenerateEvent() = 0;
|
|
|
|
virtual wxFileSystemWatcherEvent ExpectedEvent() = 0;
|
|
|
|
|
|
protected:
|
|
EventGenerator& eg;
|
|
wxEventLoopBase* m_loop; // loop reference
|
|
int m_count; // idle events count
|
|
|
|
wxFileSystemWatcher* m_watcher;
|
|
bool tested; // indicates, whether we have already passed the test
|
|
|
|
#include "wx/arrimpl.cpp"
|
|
WX_DEFINE_ARRAY_PTR(wxFileSystemWatcherEvent*, wxArrayEvent);
|
|
wxArrayEvent m_events;
|
|
wxFileSystemWatcherEvent* m_lastEvent;
|
|
};
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// test class
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class FileSystemWatcherTestCase : public CppUnit::TestCase
|
|
{
|
|
public:
|
|
FileSystemWatcherTestCase() { }
|
|
|
|
virtual void setUp();
|
|
virtual void tearDown();
|
|
|
|
protected:
|
|
wxEventLoopBase* m_loop;
|
|
|
|
private:
|
|
CPPUNIT_TEST_SUITE( FileSystemWatcherTestCase );
|
|
CPPUNIT_TEST( TestEventCreate );
|
|
CPPUNIT_TEST( TestEventDelete );
|
|
|
|
// FIXME: Currently this test fails under Windows.
|
|
#ifndef __WINDOWS__
|
|
CPPUNIT_TEST( TestTrees );
|
|
#endif // __WINDOWS__
|
|
|
|
// kqueue-based implementation doesn't collapse create/delete pairs in
|
|
// renames and doesn't detect neither modifications nor access to the
|
|
// files reliably currently so disable these tests
|
|
//
|
|
// FIXME: fix the code and reenable them
|
|
#ifndef wxHAS_KQUEUE
|
|
CPPUNIT_TEST( TestEventRename );
|
|
CPPUNIT_TEST( TestEventModify );
|
|
|
|
// MSW implementation doesn't detect file access events currently
|
|
#ifndef __WINDOWS__
|
|
CPPUNIT_TEST( TestEventAccess );
|
|
#endif // __WINDOWS__
|
|
#endif // !wxHAS_KQUEUE
|
|
|
|
CPPUNIT_TEST( TestNoEventsAfterRemove );
|
|
CPPUNIT_TEST_SUITE_END();
|
|
|
|
void TestEventCreate();
|
|
void TestEventDelete();
|
|
void TestEventRename();
|
|
void TestEventModify();
|
|
void TestEventAccess();
|
|
#ifndef __WINDOWS__
|
|
void TestTrees();
|
|
#endif // __WINDOWS__
|
|
|
|
void TestNoEventsAfterRemove();
|
|
|
|
DECLARE_NO_COPY_CLASS(FileSystemWatcherTestCase)
|
|
};
|
|
|
|
// the test currently hangs under OS X for some reason and this prevents tests
|
|
// ran by buildbot from completing so disable it until someone has time to
|
|
// debug it
|
|
//
|
|
// FIXME: debug and fix this!
|
|
#ifndef __WXOSX__
|
|
// register in the unnamed registry so that these tests are run by default
|
|
CPPUNIT_TEST_SUITE_REGISTRATION( FileSystemWatcherTestCase );
|
|
#endif
|
|
|
|
// also include in its own registry so that these tests can be run alone
|
|
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileSystemWatcherTestCase,
|
|
"FileSystemWatcherTestCase" );
|
|
|
|
void FileSystemWatcherTestCase::setUp()
|
|
{
|
|
wxLog::AddTraceMask(wxTRACE_FSWATCHER);
|
|
EventGenerator::Get().GetWatchDir();
|
|
}
|
|
|
|
void FileSystemWatcherTestCase::tearDown()
|
|
{
|
|
EventGenerator::Get().RemoveWatchDir();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// TestEventCreate
|
|
// ----------------------------------------------------------------------------
|
|
void FileSystemWatcherTestCase::TestEventCreate()
|
|
{
|
|
wxLogDebug("TestEventCreate()");
|
|
|
|
class EventTester : public EventHandler
|
|
{
|
|
public:
|
|
virtual void GenerateEvent()
|
|
{
|
|
CPPUNIT_ASSERT(eg.CreateFile());
|
|
}
|
|
|
|
virtual wxFileSystemWatcherEvent ExpectedEvent()
|
|
{
|
|
wxFileSystemWatcherEvent event(wxFSW_EVENT_CREATE);
|
|
event.SetPath(eg.m_file);
|
|
event.SetNewPath(eg.m_file);
|
|
return event;
|
|
}
|
|
};
|
|
|
|
EventTester tester;
|
|
|
|
wxLogTrace(wxTRACE_FSWATCHER, "TestEventCreate tester created()");
|
|
|
|
tester.Run();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// TestEventDelete
|
|
// ----------------------------------------------------------------------------
|
|
void FileSystemWatcherTestCase::TestEventDelete()
|
|
{
|
|
wxLogDebug("TestEventDelete()");
|
|
|
|
class EventTester : public EventHandler
|
|
{
|
|
public:
|
|
virtual void GenerateEvent()
|
|
{
|
|
CPPUNIT_ASSERT(eg.DeleteFile());
|
|
}
|
|
|
|
virtual wxFileSystemWatcherEvent ExpectedEvent()
|
|
{
|
|
wxFileSystemWatcherEvent event(wxFSW_EVENT_DELETE);
|
|
event.SetPath(eg.m_old);
|
|
|
|
// CHECK maybe new path here could be NULL or sth?
|
|
event.SetNewPath(eg.m_old);
|
|
return event;
|
|
}
|
|
};
|
|
|
|
// we need to create a file now, so we can delete it
|
|
EventGenerator::Get().CreateFile();
|
|
|
|
EventTester tester;
|
|
tester.Run();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// TestEventRename
|
|
// ----------------------------------------------------------------------------
|
|
void FileSystemWatcherTestCase::TestEventRename()
|
|
{
|
|
wxLogDebug("TestEventRename()");
|
|
|
|
class EventTester : public EventHandler
|
|
{
|
|
public:
|
|
virtual void GenerateEvent()
|
|
{
|
|
CPPUNIT_ASSERT(eg.RenameFile());
|
|
}
|
|
|
|
virtual wxFileSystemWatcherEvent ExpectedEvent()
|
|
{
|
|
wxFileSystemWatcherEvent event(wxFSW_EVENT_RENAME);
|
|
event.SetPath(eg.m_old);
|
|
event.SetNewPath(eg.m_file);
|
|
return event;
|
|
}
|
|
};
|
|
|
|
// need a file to rename later
|
|
EventGenerator::Get().CreateFile();
|
|
|
|
EventTester tester;
|
|
tester.Run();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// TestEventModify
|
|
// ----------------------------------------------------------------------------
|
|
void FileSystemWatcherTestCase::TestEventModify()
|
|
{
|
|
wxLogDebug("TestEventModify()");
|
|
|
|
class EventTester : public EventHandler
|
|
{
|
|
public:
|
|
virtual void GenerateEvent()
|
|
{
|
|
CPPUNIT_ASSERT(eg.ModifyFile());
|
|
}
|
|
|
|
virtual wxFileSystemWatcherEvent ExpectedEvent()
|
|
{
|
|
wxFileSystemWatcherEvent event(wxFSW_EVENT_MODIFY);
|
|
event.SetPath(eg.m_file);
|
|
event.SetNewPath(eg.m_file);
|
|
return event;
|
|
}
|
|
};
|
|
|
|
// we need to create a file to modify
|
|
EventGenerator::Get().CreateFile();
|
|
|
|
EventTester tester;
|
|
tester.Run();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// TestEventAccess
|
|
// ----------------------------------------------------------------------------
|
|
void FileSystemWatcherTestCase::TestEventAccess()
|
|
{
|
|
wxLogDebug("TestEventAccess()");
|
|
|
|
class EventTester : public EventHandler
|
|
{
|
|
public:
|
|
virtual void GenerateEvent()
|
|
{
|
|
CPPUNIT_ASSERT(eg.ReadFile());
|
|
}
|
|
|
|
virtual wxFileSystemWatcherEvent ExpectedEvent()
|
|
{
|
|
wxFileSystemWatcherEvent event(wxFSW_EVENT_ACCESS);
|
|
event.SetPath(eg.m_file);
|
|
event.SetNewPath(eg.m_file);
|
|
return event;
|
|
}
|
|
};
|
|
|
|
// we need to create a file to read from it and write sth to it
|
|
EventGenerator::Get().CreateFile();
|
|
EventGenerator::Get().ModifyFile();
|
|
|
|
EventTester tester;
|
|
tester.Run();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// TestTrees
|
|
// ----------------------------------------------------------------------------
|
|
#ifndef __WINDOWS__
|
|
void FileSystemWatcherTestCase::TestTrees()
|
|
{
|
|
class TreeTester : public EventHandler
|
|
{
|
|
const size_t subdirs;
|
|
const size_t files;
|
|
|
|
public:
|
|
TreeTester() : subdirs(5), files(3) {}
|
|
|
|
void GrowTree(wxFileName dir)
|
|
{
|
|
CPPUNIT_ASSERT(dir.Mkdir());
|
|
|
|
// Create a branch of 5 numbered subdirs, each containing 3
|
|
// numbered files
|
|
for ( unsigned d = 0; d < subdirs; ++d )
|
|
{
|
|
dir.AppendDir(wxString::Format("subdir%u", d+1));
|
|
CPPUNIT_ASSERT(dir.Mkdir());
|
|
|
|
const wxString prefix = dir.GetPathWithSep();
|
|
for ( unsigned f = 0; f < files; ++f )
|
|
{
|
|
// Just create the files.
|
|
wxFile(prefix + wxString::Format("file%u", f+1),
|
|
wxFile::write);
|
|
}
|
|
}
|
|
}
|
|
|
|
void RmDir(wxFileName dir)
|
|
{
|
|
CPPUNIT_ASSERT(dir.DirExists());
|
|
|
|
CPPUNIT_ASSERT(dir.Rmdir(wxPATH_RMDIR_RECURSIVE));
|
|
}
|
|
|
|
void WatchDir(wxFileName dir)
|
|
{
|
|
CPPUNIT_ASSERT(m_watcher);
|
|
|
|
// Store the initial count; there may already be some watches
|
|
const int initial = m_watcher->GetWatchedPathsCount();
|
|
|
|
m_watcher->Add(dir);
|
|
CPPUNIT_ASSERT_EQUAL(initial + 1,
|
|
m_watcher->GetWatchedPathsCount());
|
|
}
|
|
|
|
void RemoveSingleWatch(wxFileName dir)
|
|
{
|
|
CPPUNIT_ASSERT(m_watcher);
|
|
|
|
const int initial = m_watcher->GetWatchedPathsCount();
|
|
|
|
m_watcher->Remove(dir);
|
|
CPPUNIT_ASSERT_EQUAL(initial - 1,
|
|
m_watcher->GetWatchedPathsCount());
|
|
}
|
|
|
|
void WatchTree(const wxFileName& dir)
|
|
{
|
|
CPPUNIT_ASSERT(m_watcher);
|
|
|
|
const size_t
|
|
treeitems = (subdirs*files) + subdirs + 1; // +1 for the trunk
|
|
|
|
// Store the initial count; there may already be some watches
|
|
const int initial = m_watcher->GetWatchedPathsCount();
|
|
|
|
GrowTree(dir);
|
|
|
|
m_watcher->AddTree(dir);
|
|
const int plustree = m_watcher->GetWatchedPathsCount();
|
|
|
|
CPPUNIT_ASSERT_EQUAL(initial + treeitems, plustree);
|
|
|
|
m_watcher->RemoveTree(dir);
|
|
CPPUNIT_ASSERT_EQUAL(initial, m_watcher->GetWatchedPathsCount());
|
|
}
|
|
|
|
void RemoveAllWatches()
|
|
{
|
|
CPPUNIT_ASSERT(m_watcher);
|
|
|
|
m_watcher->RemoveAll();
|
|
CPPUNIT_ASSERT_EQUAL(0, m_watcher->GetWatchedPathsCount());
|
|
}
|
|
|
|
virtual void GenerateEvent()
|
|
{
|
|
// We don't use this function for events. Just run the tests
|
|
|
|
wxFileName watchdir = EventGenerator::GetWatchDir();
|
|
CPPUNIT_ASSERT(watchdir.DirExists());
|
|
|
|
wxFileName treedir(watchdir);
|
|
treedir.AppendDir("treetrunk");
|
|
CPPUNIT_ASSERT(!treedir.DirExists());
|
|
|
|
wxFileName singledir(watchdir);
|
|
singledir.AppendDir("single");
|
|
CPPUNIT_ASSERT(!singledir.DirExists());
|
|
CPPUNIT_ASSERT(singledir.Mkdir());
|
|
|
|
WatchDir(singledir);
|
|
WatchTree(treedir);
|
|
|
|
RemoveSingleWatch(singledir);
|
|
// Add it back again, ready to test RemoveAll()
|
|
WatchDir(singledir);
|
|
|
|
RemoveAllWatches();
|
|
|
|
// Clean up
|
|
RmDir(singledir);
|
|
RmDir(treedir);
|
|
|
|
Exit();
|
|
}
|
|
|
|
virtual wxFileSystemWatcherEvent ExpectedEvent()
|
|
{
|
|
CPPUNIT_FAIL("Shouldn't be called");
|
|
|
|
return wxFileSystemWatcherEvent(wxFSW_EVENT_ERROR);
|
|
}
|
|
|
|
virtual void CheckResult()
|
|
{
|
|
// Do nothing. We override this to prevent receiving events in
|
|
// ExpectedEvent()
|
|
}
|
|
};
|
|
|
|
TreeTester tester;
|
|
tester.Run();
|
|
}
|
|
#endif // __WINDOWS__
|
|
|
|
namespace
|
|
{
|
|
|
|
// We can't define this class locally inside TestNoEventsAfterRemove() for some
|
|
// reason with g++ 4.0 under OS X 10.5, it results in the following mysterious
|
|
// error:
|
|
//
|
|
// /var/tmp//ccTkNCkc.s:unknown:Non-global symbol:
|
|
// __ZThn80_ZN25FileSystemWatcherTestCase23TestNoEventsAfterRemoveEvEN11EventTester6NotifyEv.eh
|
|
// can't be a weak_definition
|
|
//
|
|
// So define this class outside the function instead.
|
|
class NoEventsAfterRemoveEventTester : public EventHandler,
|
|
public wxTimer
|
|
{
|
|
public:
|
|
NoEventsAfterRemoveEventTester()
|
|
{
|
|
// We need to use an inactivity timer as we never get any file
|
|
// system events in this test, so we consider that the test is
|
|
// finished when this 1s timeout expires instead of, as usual,
|
|
// stopping after getting the file system events.
|
|
Start(1000, true);
|
|
}
|
|
|
|
virtual void GenerateEvent()
|
|
{
|
|
m_watcher->Remove(EventGenerator::GetWatchDir());
|
|
CPPUNIT_ASSERT(eg.CreateFile());
|
|
}
|
|
|
|
virtual void CheckResult()
|
|
{
|
|
CPPUNIT_ASSERT( m_events.empty() );
|
|
}
|
|
|
|
virtual wxFileSystemWatcherEvent ExpectedEvent()
|
|
{
|
|
CPPUNIT_FAIL( "Shouldn't be called" );
|
|
|
|
return wxFileSystemWatcherEvent(wxFSW_EVENT_ERROR);
|
|
}
|
|
|
|
virtual void Notify()
|
|
{
|
|
SendIdle();
|
|
}
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
void FileSystemWatcherTestCase::TestNoEventsAfterRemove()
|
|
{
|
|
NoEventsAfterRemoveEventTester tester;
|
|
tester.Run();
|
|
}
|