| // Copyright 2007-2009 Google Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // ======================================================================== |
| |
| #include "omaha/test/step_test.h" |
| |
| const TCHAR *StepTestBase::RESUME_EVENT_TEMPLATE = _T("R %s"); |
| const TCHAR *StepTestBase::STEP_REACHED_EVENT_TEMPLATE = _T("SR %s"); |
| const TCHAR *StepTestBase::STATE_REG_KEY_TEMPLATE = _T("SOFTWARE\\GAT %s"); |
| const TCHAR *StepTestBase::STATE_REG_VALUE_NAME = _T("state"); |
| |
| StepTestBase::StepTestBase(const TCHAR*) : step_reached_event_(NULL), |
| resume_event_(NULL), state_key_(NULL) { |
| } |
| |
| void StepTestBase::Terminate() { |
| CloseHandle(step_reached_event_); |
| CloseHandle(resume_event_); |
| RegCloseKey(state_key_); |
| } |
| |
| StepTestBase::~StepTestBase() { |
| Terminate(); |
| } |
| |
| StepTestStepper::StepTestStepper(const TCHAR* name) : |
| StepTestBase(name), |
| is_someone_listening_(false) { |
| CString namebuf; |
| |
| // A "broadcaster" is a program that notifies the "listener" program that |
| // the broadcaster has reached an interesting point in its execution, and |
| // the listener should check state. |
| // |
| // Results will be unpredictable if two broadcasters are running at the |
| // same time. However, since a broadcaster will only open the resume event |
| // and not create it, we shouldn't see any problems where two broadcasters |
| // deadlock each other. |
| namebuf.Format(RESUME_EVENT_TEMPLATE, name); |
| resume_event_ = OpenEvent(EVENT_ALL_ACCESS, FALSE, namebuf); |
| if (resume_event_ != NULL) { |
| is_someone_listening_ = true; |
| |
| namebuf.Format(STEP_REACHED_EVENT_TEMPLATE, name); |
| step_reached_event_ = OpenEvent(EVENT_ALL_ACCESS, FALSE, namebuf); |
| |
| namebuf.Format(STATE_REG_KEY_TEMPLATE, name); |
| RegCreateKeyEx(HKEY_CURRENT_USER, namebuf, 0, NULL, REG_OPTION_VOLATILE, |
| KEY_READ | KEY_WRITE, NULL, &state_key_, NULL); |
| } else { |
| Terminate(); |
| } |
| } |
| |
| StepTestStepper::~StepTestStepper() { |
| Terminate(); |
| } |
| |
| void StepTestStepper::Step(DWORD step) { |
| if (!is_someone_listening_) { |
| return; |
| } |
| RegSetValueEx(state_key_, STATE_REG_VALUE_NAME, 0, REG_DWORD, |
| reinterpret_cast<BYTE*>(&step), sizeof(step)); |
| SetEvent(step_reached_event_); |
| WaitForSingleObject(resume_event_, INFINITE); |
| } |
| |
| StepTestWatcher::StepTestWatcher(const TCHAR* name) : StepTestBase(name), |
| name_(name) { |
| } |
| |
| StepTestWatcher::~StepTestWatcher() { |
| Terminate(); |
| } |
| |
| void StepTestWatcher::Go() { |
| DWORD step = 0; |
| bool done = false; |
| |
| PrintIntroduction(); |
| |
| printf("Verifying preconditions...\r\n"); |
| bool passed = VerifyStep(0, &done); |
| if (passed) { |
| _tprintf(_T("Preconditions OK.\r\n")); |
| } else { |
| _tprintf(_T("*** Preconditions FAILED. ***\r\n")); |
| } |
| |
| CString namebuf; |
| |
| namebuf.Format(RESUME_EVENT_TEMPLATE, name_); |
| resume_event_ = CreateEvent(NULL, FALSE, FALSE, namebuf); |
| namebuf.Format(STEP_REACHED_EVENT_TEMPLATE, name_); |
| step_reached_event_ = CreateEvent(NULL, FALSE, FALSE, namebuf); |
| |
| namebuf.Format(STATE_REG_KEY_TEMPLATE, name_); |
| RegCreateKeyEx(HKEY_CURRENT_USER, namebuf, 0, NULL, REG_OPTION_VOLATILE, |
| KEY_READ, NULL, &state_key_, NULL); |
| |
| printf("Begin test now.\r\n"); |
| |
| done = false; |
| while (!done) { |
| WaitForSingleObject(step_reached_event_, INFINITE); |
| DWORD step_size = sizeof(step); |
| RegQueryValueEx(state_key_, STATE_REG_VALUE_NAME, NULL, NULL, |
| reinterpret_cast<BYTE*>(&step), &step_size); |
| printf("Testing step %d.\r\n", step); |
| passed = VerifyStep(step, &done); |
| if (!passed) { |
| _tprintf(_T("\r\n\r\n*** TEST FAILURE: Step %d. ***\r\nr\n"), step); |
| } |
| SetEvent(resume_event_); |
| } |
| |
| PrintConclusion(); |
| } |
| |
| bool StepTestWatcher::RegistryKeyExists(HKEY root, const TCHAR* name) { |
| HKEY key; |
| LONG result = RegOpenKeyEx(root, name, 0, KEY_READ, &key); |
| if (ERROR_SUCCESS == result) { |
| RegCloseKey(key); |
| return true; |
| } |
| return false; |
| } |
| |
| bool StepTestWatcher::RegistryValueExists(HKEY root, const TCHAR* key_name, |
| const TCHAR* value_name) { |
| bool result = false; |
| HKEY key; |
| LONG reg_result = RegOpenKeyEx(root, key_name, 0, KEY_READ, &key); |
| if (ERROR_SUCCESS == reg_result) { |
| DWORD dummy_size = 0; |
| reg_result = RegQueryValueEx(key, value_name, NULL, NULL, NULL, |
| &dummy_size); |
| if (reg_result == ERROR_SUCCESS && dummy_size > 0) { |
| result = true; |
| } |
| RegCloseKey(key); |
| } |
| return result; |
| } |