xref: /glogg/tests/watchtowerTest.cpp (revision 84af0c9b75fb9369ab66df476dd881cd6d30efcf)
1 #include "gmock/gmock.h"
2 
3 #include <fcntl.h>
4 
5 #include <memory>
6 #include <condition_variable>
7 #include <thread>
8 #include <mutex>
9 #include <chrono>
10 
11 #include "inotifywatchtower.h"
12 
13 using namespace std;
14 using namespace testing;
15 
16 class WatchTowerBehaviour: public testing::Test {
17   public:
18     INotifyWatchTower watch_tower;
19 
20     void SetUp() override {
21 #ifdef _WIN32
22         file_watcher = make_shared<WinFileWatcher>();
23 #endif
24     }
25 
26     string createTempEmptyFile() {
27         // I know tmpnam is bad but I need control over the file
28         // and it is the only one which exits on Windows.
29         char* file_name = tmpnam( nullptr );
30         int fd = creat( file_name, S_IRUSR | S_IWUSR );
31         close( fd );
32 
33         return string( file_name );
34     }
35 
36     string getNonExistingFileName() {
37         return string( tmpnam( nullptr ) );
38     }
39 };
40 
41 TEST_F( WatchTowerBehaviour, AcceptsAnExistingFileToWatch ) {
42     auto file_name = createTempEmptyFile();
43     auto registration = watch_tower.addFile( file_name, [] (void) { } );
44 }
45 
46 TEST_F( WatchTowerBehaviour, AcceptsANonExistingFileToWatch ) {
47     auto registration = watch_tower.addFile( getNonExistingFileName(), [] (void) { } );
48 }
49 
50 class WatchTowerSingleFile: public WatchTowerBehaviour {
51   public:
52     static const int TIMEOUT = 100;
53 
54     string file_name;
55     INotifyWatchTower::Registration registration;
56 
57     mutex mutex_;
58     condition_variable cv_;
59     bool notification_received = false;
60 
61     void SetUp() override {
62         file_name = createTempEmptyFile();
63         registration = watch_tower.addFile( file_name, [this] (void) {
64             unique_lock<mutex> lock(mutex_);
65             notification_received = true;
66             cv_.notify_one(); } );
67     }
68 
69     bool waitNotificationReceived() {
70         unique_lock<mutex> lock(mutex_);
71         return cv_.wait_for( lock, std::chrono::milliseconds(100),
72                 [this] { return notification_received; } );
73     }
74 
75     void appendDataToFile( const string& file_name ) {
76         static const char* string = "Test line\n";
77         int fd = open( file_name.c_str(), O_WRONLY | O_APPEND );
78         write( fd, (void*) string, strlen( string ) );
79         close( fd );
80     }
81 };
82 
83 TEST_F( WatchTowerSingleFile, SignalsWhenAWatchedFileIsAppended ) {
84     appendDataToFile( file_name );
85     ASSERT_TRUE( waitNotificationReceived() );
86 }
87 
88 TEST_F( WatchTowerSingleFile, StopSignalingWhenWatchDeleted ) {
89     remove( file_name.c_str() );
90     ASSERT_TRUE( waitNotificationReceived() );
91 }
92