blob: b3bd353031f07ce3ab34b3306e5465af4c54f1d0 [file] [log] [blame]
// 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 <windows.h>
#include <objbase.h>
#include "base/scoped_ptr.h"
#include "omaha/common/error.h"
#include "omaha/common/scoped_any.h"
#include "omaha/common/utils.h"
#include "omaha/common/thread_pool.h"
#include "omaha/common/timer.h"
#include "omaha/goopdate/request.h"
#include "omaha/testing/unit_test.h"
#include "omaha/worker/application_data.h"
#include "omaha/worker/ping.h"
namespace omaha {
// Sends a ping when run in a thread pool.
class PingJob : public UserWorkItem {
public:
PingJob(Ping* ping, Request* request, HRESULT* result)
: ping_(ping),
request_(request),
result_(result) {}
private:
virtual void DoProcess() {
scoped_co_init init_com_apt(COINIT_MULTITHREADED);
*result_ = ping_->SendPing(request_);
}
Ping* ping_;
Request* request_;
HRESULT* result_;
DISALLOW_EVIL_CONSTRUCTORS(PingJob);
};
class PingTest : public testing::Test {
public:
PingTest() : ping_result_(E_FAIL) {}
protected:
virtual void SetUp() {
ping_result_ = E_FAIL;
thread_pool_.reset(new ThreadPool);
EXPECT_HRESULT_SUCCEEDED(thread_pool_->Initialize(kShutdownDelayMs));
ping_.reset(new Ping);
AppData data(StringToGuid(_T("{C6E96DF3-BFEA-4403-BAA7-8920CE0B494A}")),
true);
CreateTestAppData(&data);
request_.reset(CreateRequest(true,
data,
PingEvent::EVENT_INSTALL_DOWNLOAD_FINISH,
PingEvent::EVENT_RESULT_SUCCESS,
0));
ASSERT_TRUE(request_.get());
}
virtual void TearDown() {
// ThreadPool destructor blocks waiting for the work items to complete.
thread_pool_.reset();
request_.reset();
ping_.reset();
}
void CreateTestAppData(AppData* expected_app) {
ASSERT_TRUE(expected_app != NULL);
expected_app->set_version(_T("1.1.1.3"));
expected_app->set_previous_version(_T("1.0.0.0"));
expected_app->set_language(_T("abc"));
expected_app->set_did_run(AppData::ACTIVE_RUN);
expected_app->set_ap(_T("Test ap"));
expected_app->set_tt_token(_T("Test TT Token"));
expected_app->set_iid(
StringToGuid(_T("{F723495F-8ACF-4746-8240-643741C797B5}")));
expected_app->set_brand_code(_T("GOOG"));
expected_app->set_client_id(_T("someclient"));
}
Request* CreateRequest(bool is_machine,
const AppData& app,
PingEvent::Types type,
PingEvent::Results result,
int error_code) {
scoped_ptr<Request> req(new Request(is_machine));
AppRequestData app_request_data(app);
PingEvent ping_event(type,
result,
error_code,
8675309,
app.previous_version());
app_request_data.AddPingEvent(ping_event);
AppRequest app_request(app_request_data);
req->AddAppRequest(app_request);
return req.release();
}
HRESULT ping_result_;
scoped_ptr<ThreadPool> thread_pool_;
scoped_ptr<Ping> ping_;
scoped_ptr<Request> request_;
static const int kShutdownDelayMs = 60 * 1000; // 60 seconds.
};
TEST_F(PingTest, SendPing) {
// The same Ping instance can send multiple pings.
EXPECT_HRESULT_SUCCEEDED(ping_->SendPing(request_.get()));
EXPECT_HRESULT_SUCCEEDED(ping_->SendPing(request_.get()));
}
// Runs a ping instance in a thread pool and attempts to cancel it.
// Either the ping succeeds or it is canceled.
TEST_F(PingTest, CancelPing) {
scoped_ptr<UserWorkItem> work_item(new PingJob(ping_.get(),
request_.get(),
&ping_result_));
EXPECT_HRESULT_SUCCEEDED(thread_pool_->QueueUserWorkItem(work_item.get(),
WT_EXECUTEDEFAULT));
work_item.release();
// Sleep for a while to give the ping some time to run.
::Sleep(100);
EXPECT_HRESULT_SUCCEEDED(ping_->Cancel());
// Wait for the ping work item to complete.
LowResTimer timer(true);
while (thread_pool_->HasWorkItems() && timer.GetSeconds() <= 60) {
::Sleep(20);
}
EXPECT_TRUE(SUCCEEDED(ping_result_) ||
ping_result_ == OMAHA_NET_E_REQUEST_CANCELLED);
}
TEST_F(PingTest, SendEmptyPing) {
Request req(false);
req.AddAppRequest(AppRequest(AppRequestData(AppData())));
EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_NO_DATA), ping_->SendPing(&req));
}
TEST_F(PingTest, SendPing_GoogleUpdateEulaNotAccepted) {
RegKey::DeleteKey(kRegistryHiveOverrideRoot);
OverrideRegistryHives(kRegistryHiveOverrideRoot);
EXPECT_SUCCEEDED(RegKey::SetValue(MACHINE_REG_UPDATE,
_T("eulaaccepted"),
static_cast<DWORD>(0)));
EXPECT_EQ(GOOPDATE_E_CANNOT_USE_NETWORK, ping_->SendPing(request_.get()));
RestoreRegistryHives();
RegKey::DeleteKey(kRegistryHiveOverrideRoot);
}
} // namespace omaha