| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 #include <gtest/gtest.h> | 
|  | 2 #include "../process.h" | 
|  | 3 #include <functional> | 
|  | 4 | 
|  | 5 // Turn off warnings for string copies | 
|  | 6 #pragma warning( disable : 4996 ) | 
|  | 7 | 
|  | 8 //------------------------------------------------------- | 
|  | 9 // Comparison objects | 
|  | 10 //------------------------------------------------------- | 
|  | 11 | 
|  | 12 const wchar_t * multiple_module_names[] = { L"kernel32.dll", L"non-matching-name
     " } ; | 
|  | 13 const wchar_t * non_existent_module_names[] = { L"non-matching-name" } ; | 
|  | 14 | 
|  | 15 const wchar_t exact_exe_name[] = L"installer-ca-tests.exe" ; | 
|  | 16 const std::wstring exact_exe_string( exact_exe_name ) ; | 
|  | 17 const wstring_ci exact_exe_string_ci( exact_exe_name ) ; | 
|  | 18 | 
|  | 19 const wchar_t mixedcase_exe_name[] = L"Installer-CA-Tests.exe" ; | 
|  | 20 const wstring_ci mixedcase_exe_string_ci( mixedcase_exe_name ) ; | 
|  | 21 | 
|  | 22 const wchar_t unknown_name[] = L"non-matching-name" ; | 
|  | 23 const wchar_t * multiple_exe_names[] = { mixedcase_exe_name, unknown_name } ; | 
|  | 24 | 
|  | 25 /** | 
|  | 26  * Compare to our own process name, case-sensitive, no length limit | 
|  | 27  */ | 
|  | 28 struct our_process_by_name | 
|  | 29   : std::unary_function< PROCESSENTRY32W, bool > | 
|  | 30 { | 
|  | 31   bool operator()( const PROCESSENTRY32W & process ) | 
|  | 32   { | 
|  | 33     return std::wstring( process.szExeFile ) == exact_exe_string ; | 
|  | 34   } ; | 
|  | 35 }; | 
|  | 36 | 
|  | 37 /** | 
|  | 38  * Compare to our own process name, case-insensitive, no length limit | 
|  | 39  */ | 
|  | 40 struct our_process_by_name_CI | 
|  | 41   : std::unary_function< PROCESSENTRY32W, bool > | 
|  | 42 { | 
|  | 43   bool operator()( const PROCESSENTRY32W & process ) | 
|  | 44   { | 
|  | 45     return wstring_ci( process.szExeFile ) == mixedcase_exe_string_ci ; | 
|  | 46   } ; | 
|  | 47 } ; | 
|  | 48 | 
|  | 49 | 
|  | 50 struct our_process_by_name_subclassed | 
|  | 51   : public process_by_any_exe_with_any_module | 
|  | 52 { | 
|  | 53   our_process_by_name_subclassed() | 
|  | 54     : process_by_any_exe_with_any_module( file_name_set( multiple_exe_names ), f
     ile_name_set() ) | 
|  | 55   {} | 
|  | 56 } ; | 
|  | 57 | 
|  | 58 | 
|  | 59 //------------------------------------------------------- | 
|  | 60 //------------------------------------------------------- | 
|  | 61 /** | 
|  | 62  * Filter by process name. Comparison is case-insensitive. | 
|  | 63  */ | 
|  | 64 class process_by_any_file_name_CI | 
|  | 65   : public std::unary_function< PROCESSENTRY32W, bool > | 
|  | 66 { | 
|  | 67   const file_name_set & names ; | 
|  | 68 public: | 
|  | 69   bool operator()( const PROCESSENTRY32W & process) | 
|  | 70   { | 
|  | 71     return names.find( process.szExeFile ) != names.end() ; | 
|  | 72   } | 
|  | 73   process_by_any_file_name_CI( const file_name_set & names ) | 
|  | 74     : names( names ) | 
|  | 75   {} | 
|  | 76 } ; | 
|  | 77 | 
|  | 78 /** | 
|  | 79  * Filter by process name. Comparison is case-insensitive. | 
|  | 80  */ | 
|  | 81 class process_by_name_CI | 
|  | 82   : public std::unary_function< PROCESSENTRY32W, bool > | 
|  | 83 { | 
|  | 84   const wstring_ci _name ; | 
|  | 85 public: | 
|  | 86   bool operator()( const PROCESSENTRY32W & process ) | 
|  | 87   { | 
|  | 88     return _name == wstring_ci( process.szExeFile ) ; | 
|  | 89   } | 
|  | 90 | 
|  | 91   process_by_name_CI( const wchar_t * name ) | 
|  | 92     : _name( name ) | 
|  | 93   {} | 
|  | 94 } ; | 
|  | 95 | 
|  | 96 //------------------------------------------------------- | 
|  | 97 // TESTS, no snapshots | 
|  | 98 //------------------------------------------------------- | 
|  | 99 PROCESSENTRY32 process_with_name( const wchar_t * s ) | 
|  | 100 { | 
|  | 101   PROCESSENTRY32W p ; | 
|  | 102   wcsncpy( p.szExeFile, s, MAX_PATH ) ; | 
|  | 103   return p ; | 
|  | 104 } | 
|  | 105 | 
|  | 106 PROCESSENTRY32 process_empty = process_with_name( L"" ) ; | 
|  | 107 PROCESSENTRY32 process_exact = process_with_name( exact_exe_name ) ; | 
|  | 108 PROCESSENTRY32 process_mixedcase = process_with_name( mixedcase_exe_name ) ; | 
|  | 109 PROCESSENTRY32 process_explorer = process_with_name( L"explorer.exe" ) ; | 
|  | 110 PROCESSENTRY32 process_absent = process_with_name( L"no_such_name" ) ; | 
|  | 111 | 
|  | 112 file_name_set multiple_name_set( multiple_exe_names ) ; | 
|  | 113 file_name_set multiple_name_set_modules( multiple_module_names ) ; | 
|  | 114 file_name_set non_existent_name_set_modules( non_existent_module_names ) ; | 
|  | 115 process_by_any_file_name_CI find_in_set( multiple_name_set ) ; | 
|  | 116 process_by_any_exe_with_any_module find_in_set_w_kernel32( multiple_name_set, mu
     ltiple_name_set_modules ) ; | 
|  | 117 process_by_any_exe_with_any_module find_in_set_w_non_existent( multiple_name_set
     , non_existent_name_set_modules ) ; | 
|  | 118 | 
|  | 119 TEST( file_name_set, validate_setup ) | 
|  | 120 { | 
|  | 121   ASSERT_EQ( 2u, multiple_name_set.size() ) ; | 
|  | 122   ASSERT_TRUE( multiple_name_set.find( exact_exe_string_ci ) != multiple_name_se
     t.end() ) ; | 
|  | 123   ASSERT_TRUE( multiple_name_set.find( mixedcase_exe_string_ci ) != multiple_nam
     e_set.end() ) ; | 
|  | 124   ASSERT_TRUE( multiple_name_set.find( L"" ) == multiple_name_set.end() ) ; | 
|  | 125   ASSERT_TRUE( multiple_name_set.find( L"not-in-list" ) == multiple_name_set.end
     () ) ; | 
|  | 126 } | 
|  | 127 | 
|  | 128 TEST( process_by_any_file_name_CI, empty ) | 
|  | 129 { | 
|  | 130   file_name_set s ; | 
|  | 131   process_by_any_file_name_CI x( s ) ; | 
|  | 132 | 
|  | 133   ASSERT_FALSE( x( process_empty ) ) ; | 
|  | 134   ASSERT_FALSE( x( process_exact ) ) ; | 
|  | 135   ASSERT_FALSE( x( process_mixedcase ) ) ; | 
|  | 136   ASSERT_FALSE( x( process_explorer ) ) ; | 
|  | 137   ASSERT_FALSE( x( process_absent ) ) ; | 
|  | 138 } | 
|  | 139 | 
|  | 140 TEST( process_by_any_file_name_CI, single_element_known ) | 
|  | 141 { | 
|  | 142   const wchar_t * elements[ 1 ] = { exact_exe_name } ; | 
|  | 143   file_name_set s( elements ) ; | 
|  | 144   process_by_any_file_name_CI x( s ) ; | 
|  | 145 | 
|  | 146   ASSERT_FALSE( x( process_empty ) ) ; | 
|  | 147   ASSERT_TRUE( x( process_exact ) ) ; | 
|  | 148   ASSERT_TRUE( x( process_mixedcase ) ) ; | 
|  | 149   ASSERT_FALSE( x( process_explorer ) ) ; | 
|  | 150   ASSERT_FALSE( x( process_absent ) ) ; | 
|  | 151 } | 
|  | 152 | 
|  | 153 TEST( process_by_any_file_name_CI, single_element_unknown ) | 
|  | 154 { | 
|  | 155   const wchar_t * elements[ 1 ] = { unknown_name } ; | 
|  | 156   file_name_set s( elements ) ; | 
|  | 157   process_by_any_file_name_CI x( s ) ; | 
|  | 158 | 
|  | 159   ASSERT_FALSE( x( process_empty ) ) ; | 
|  | 160   ASSERT_FALSE( x( process_exact ) ) ; | 
|  | 161   ASSERT_FALSE( x( process_mixedcase ) ) ; | 
|  | 162   ASSERT_FALSE( x( process_explorer ) ) ; | 
|  | 163   ASSERT_FALSE( x( process_absent ) ) ; | 
|  | 164 } | 
|  | 165 | 
|  | 166 TEST( process_by_any_file_name_CI, two_elements ) | 
|  | 167 { | 
|  | 168   file_name_set s( multiple_exe_names ) ; | 
|  | 169   process_by_any_file_name_CI x( s ) ; | 
|  | 170 | 
|  | 171   ASSERT_FALSE( find_in_set( process_empty ) ) ; | 
|  | 172   ASSERT_TRUE( find_in_set( process_exact ) ) ; | 
|  | 173   ASSERT_TRUE( find_in_set( process_mixedcase ) ) ; | 
|  | 174   ASSERT_FALSE( find_in_set( process_explorer ) ) ; | 
|  | 175   ASSERT_FALSE( find_in_set( process_absent ) ) ; | 
|  | 176 } | 
|  | 177 | 
|  | 178 //------------------------------------------------------- | 
|  | 179 // Single-snapshot version of initializers | 
|  | 180 //------------------------------------------------------- | 
|  | 181 /** | 
|  | 182  * Single-snapshot version of initialize_process_list, for testing. | 
|  | 183  */ | 
|  | 184 template< class T, class Admittance, class Extractor > | 
|  | 185 void initialize_process_list( std::vector< T > & v, Admittance admit = Admittanc
     e(), Extractor extract = Extractor() ) | 
|  | 186 { | 
|  | 187   initialize_process_list( v, Process_Snapshot(), admit, extract ) ; | 
|  | 188 } | 
|  | 189 | 
|  | 190 /** | 
|  | 191  * Single-snapshot version of initialize_process_set, for testing. | 
|  | 192  */ | 
|  | 193 template< class T, class Admittance, class Extractor > | 
|  | 194 void initialize_process_set( std::set< T > & s, Admittance admit = Admittance(),
      Extractor extract = Extractor() ) | 
|  | 195 { | 
|  | 196   initialize_process_set( s, Process_Snapshot(), admit, extract ) ; | 
|  | 197 } | 
|  | 198 | 
|  | 199 //------------------------------------------------------- | 
|  | 200 // TESTS with snapshots | 
|  | 201 //------------------------------------------------------- | 
|  | 202 /** | 
|  | 203  * Construction test ensures that we don't throw and that at least one process s
     hows up. | 
|  | 204  */ | 
|  | 205 TEST( Process_List_Test, construct_vector ) | 
|  | 206 { | 
|  | 207   std::vector< PROCESSENTRY32W > v ; | 
|  | 208   initialize_process_list( v, every_process(), copy_all() ) ; | 
|  | 209   ASSERT_GE( v.size(), 1u ); | 
|  | 210 } | 
|  | 211 | 
|  | 212 /** | 
|  | 213  * The only process we are really guaranteed to have is this test process itself
     . | 
|  | 214  */ | 
|  | 215 TEST( Process_List_Test, find_our_process ) | 
|  | 216 { | 
|  | 217   std::vector< PROCESSENTRY32W > v ; | 
|  | 218   initialize_process_list( v, our_process_by_name(), copy_all() ) ; | 
|  | 219   size_t size( v.size() ); | 
|  | 220   EXPECT_EQ( 1u, size );    // Please, don't run multiple test executables simul
     taneously | 
|  | 221   ASSERT_GE( 1u, size ); | 
|  | 222 } | 
|  | 223 | 
|  | 224 /** | 
|  | 225  * The only process we are really guaranteed to have is this test process itself
     . | 
|  | 226  * This test uses same one used in Process_Closer | 
|  | 227  */ | 
|  | 228 TEST( Process_List_Test, find_our_process_CI_generic ) | 
|  | 229 { | 
|  | 230   std::vector< PROCESSENTRY32W > v ; | 
|  | 231   initialize_process_list( v, process_by_name_CI( mixedcase_exe_name ), copy_all
     () ) ; | 
|  | 232   size_t size( v.size() ); | 
|  | 233   EXPECT_EQ( 1u, size );    // Please, don't run multiple test executables simul
     taneously | 
|  | 234   ASSERT_GE( 1u, size ); | 
|  | 235 } | 
|  | 236 | 
|  | 237 /** | 
|  | 238  * The only process we are really guaranteed to have is this test process itself
     . | 
|  | 239  * This test uses the generic filter function. | 
|  | 240  */ | 
|  | 241 TEST( Process_List_Test, find_our_process_CI_as_used ) | 
|  | 242 { | 
|  | 243   std::vector< PROCESSENTRY32W > v ; | 
|  | 244   initialize_process_list( v, process_by_any_file_name_CI( file_name_set( multip
     le_exe_names ) ), copy_all() ) ; | 
|  | 245   size_t size( v.size() ); | 
|  | 246   EXPECT_EQ( 1u, size );    // Please, don't run multiple test executables simul
     taneously | 
|  | 247   ASSERT_GE( 1u, size ); | 
|  | 248 } | 
|  | 249 | 
|  | 250 /** | 
|  | 251  * Locate the PID of our process. | 
|  | 252  */ | 
|  | 253 TEST( Process_List_Test, find_our_PID ) | 
|  | 254 { | 
|  | 255   std::vector< DWORD > v ; | 
|  | 256   initialize_process_list( v, our_process_by_name(), copy_PID() ) ; | 
|  | 257   size_t size( v.size() ); | 
|  | 258   EXPECT_EQ( size, 1u );    // Please, don't run multiple test executables simul
     taneously | 
|  | 259   ASSERT_GE( size, 1u ); | 
|  | 260 } | 
|  | 261 | 
|  | 262 /** | 
|  | 263  * Locate the PID of our process using the | 
|  | 264  */ | 
|  | 265 TEST( Process_List_Test, find_our_process_in_set ) | 
|  | 266 { | 
|  | 267   std::vector< DWORD > v ; | 
|  | 268   initialize_process_list( v, find_in_set, copy_PID() ) ; | 
|  | 269   size_t size( v.size() ); | 
|  | 270   EXPECT_EQ( size, 1u );    // Please, don't run multiple test executables simul
     taneously | 
|  | 271   ASSERT_GE( size, 1u ); | 
|  | 272 } | 
|  | 273 | 
|  | 274 //------------------------------------------------------- | 
|  | 275 // TESTS for process ID sets | 
|  | 276 //------------------------------------------------------- | 
|  | 277 /* | 
|  | 278  * Can't use copy_all without a definition for "less< PROCESSENTRY32W >". | 
|  | 279  * Thus all tests only use copy_PID | 
|  | 280  */ | 
|  | 281 | 
|  | 282 /** | 
|  | 283  * Construction test ensures that we don't throw and that at least one process s
     hows up. | 
|  | 284  */ | 
|  | 285 TEST( pid_set, construct_set ) | 
|  | 286 { | 
|  | 287   std::set< DWORD > s ; | 
|  | 288   initialize_process_set( s, every_process(), copy_PID() ) ; | 
|  | 289   ASSERT_GE( s.size(), 1u ); | 
|  | 290 } | 
|  | 291 | 
|  | 292 TEST( pid_set, find_our_process_in_set ) | 
|  | 293 { | 
|  | 294   std::set< DWORD > s ; | 
|  | 295   initialize_process_set( s, find_in_set, copy_PID() ) ; | 
|  | 296   size_t size( s.size() ) ; | 
|  | 297   EXPECT_EQ( size, 1u ); | 
|  | 298   ASSERT_GE( size, 1u ); | 
|  | 299 } | 
|  | 300 | 
|  | 301 TEST( pid_set, find_our_process_in_set_w_kernel32 ) | 
|  | 302 { | 
|  | 303   std::set< DWORD > s ; | 
|  | 304   initialize_process_set( s, find_in_set_w_kernel32, copy_PID() ) ; | 
|  | 305   size_t size( s.size() ) ; | 
|  | 306   EXPECT_EQ( size, 1u ); | 
|  | 307   ASSERT_GE( size, 1u ); | 
|  | 308 } | 
|  | 309 TEST( pid_set, find_our_process_in_set_w_non_existant ) | 
|  | 310 { | 
|  | 311   std::set< DWORD > s ; | 
|  | 312   initialize_process_set( s, find_in_set_w_non_existent, copy_PID() ) ; | 
|  | 313   size_t size( s.size() ) ; | 
|  | 314   EXPECT_EQ( size, 0u ); | 
|  | 315   ASSERT_GE( size, 0u ); | 
|  | 316 } | 
| OLD | NEW | 
|---|