| Index: third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.cc
|
| diff --git a/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.cc b/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..27c602c8a3e60a912aad80fa057ef412b87910be
|
| --- /dev/null
|
| +++ b/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.cc
|
| @@ -0,0 +1,254 @@
|
| +// Copyright 2012 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.
|
| +
|
| +//
|
| +// Helper classes for tests including a mock Scheduler, a mock network and a
|
| +// mock storage layer.
|
| +
|
| +#include <set>
|
| +
|
| +#include "google/cacheinvalidation/impl/proto-converter.h"
|
| +#include "google/cacheinvalidation/test/test-utils.h"
|
| +#include "google/cacheinvalidation/test/test-logger.h"
|
| +#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
|
| +
|
| +namespace invalidation {
|
| +
|
| +using ::google::protobuf::io::StringOutputStream;
|
| +using ::testing::DeleteArg;
|
| +using ::testing::StrictMock;
|
| +
|
| +// Creates an Action InvokeNetworkStatusCallback<k>() that calls the Run method
|
| +// on the kth argument with value |true|.
|
| +ACTION_TEMPLATE(
|
| + InvokeNetworkStatusCallback,
|
| + HAS_1_TEMPLATE_PARAMS(int, k),
|
| + AND_0_VALUE_PARAMS()) {
|
| + std::tr1::get<k>(args)->Run(true);
|
| +}
|
| +
|
| +const char* UnitTestBase::kClientToken = "Dummy";
|
| +
|
| +void UnitTestBase::SetUp() {
|
| + // Start time at an arbitrary point, just to make sure we don't depend on it
|
| + // being 0.
|
| + start_time = Time() + TimeDelta::FromDays(9);
|
| + statistics.reset(new Statistics());
|
| + reg_summary.reset(new RegistrationSummary());
|
| + InitZeroRegistrationSummary(reg_summary.get());
|
| + InitSystemResources(); // Set up system resources
|
| + message_callback = NULL;
|
| +
|
| + // Start the scheduler and resources.
|
| + internal_scheduler->StartScheduler();
|
| + resources->Start();
|
| +}
|
| +
|
| +void UnitTestBase::TearDown() {
|
| + if (message_callback != NULL) {
|
| + delete message_callback;
|
| + message_callback = NULL;
|
| + }
|
| +}
|
| +
|
| +void UnitTestBase::InitSystemResources() {
|
| + logger = new TestLogger();
|
| +
|
| + // Use a deterministic scheduler for the protocol handler's internals, since
|
| + // we want precise control over when batching intervals expire.
|
| + internal_scheduler = new DeterministicScheduler(logger);
|
| + internal_scheduler->SetInitialTime(start_time);
|
| +
|
| + // Use a mock network to let us trap the protocol handler's message receiver
|
| + // and its attempts to send messages.
|
| + network = new StrictMock<MockNetwork>();
|
| + listener_scheduler = new StrictMock<MockScheduler>();
|
| +
|
| + // Storage shouldn't be used by the protocol handler, so use a strict mock
|
| + // to catch any accidental calls.
|
| + storage = new StrictMock<MockStorage>();
|
| +
|
| + // The BasicSystemResources will set itself in the components.
|
| + EXPECT_CALL(*network, SetSystemResources(_));
|
| + EXPECT_CALL(*storage, SetSystemResources(_));
|
| + EXPECT_CALL(*listener_scheduler, SetSystemResources(_));
|
| +
|
| + // Create the actual resources.
|
| + resources.reset(new BasicSystemResources(
|
| + logger, internal_scheduler, listener_scheduler, network, storage,
|
| + "unit-test"));
|
| +}
|
| +
|
| +void UnitTestBase::InitCommonExpectations() {
|
| + // When we construct the protocol handler, it will set a message receiver on
|
| + // the network. Intercept the call and save the callback.
|
| + EXPECT_CALL(*network, SetMessageReceiver(_))
|
| + .WillOnce(SaveArg<0>(&message_callback));
|
| +
|
| + // It will also add a network status receiver. The network channel takes
|
| + // ownership. Invoke it once with |true| just to exercise that code path,
|
| + // then delete it since we won't need it anymore.
|
| + EXPECT_CALL(*network, AddNetworkStatusReceiver(_))
|
| + .WillOnce(DoAll(InvokeNetworkStatusCallback<0>(), DeleteArg<0>()));
|
| +}
|
| +
|
| +void UnitTestBase::InitRegistrationMessage(const vector<ObjectIdP>& oids,
|
| + bool is_reg, RegistrationMessage *reg_message) {
|
| + RegistrationP::OpType op_type = is_reg ?
|
| + RegistrationP::REGISTER : RegistrationP::UNREGISTER;
|
| + for (size_t i = 0; i < oids.size(); i++) {
|
| + ProtoHelpers::InitRegistrationP(
|
| + oids[i], op_type, reg_message->add_registration());
|
| + }
|
| +}
|
| +
|
| +void UnitTestBase::InitErrorMessage(ErrorMessage::Code error_code,
|
| + const string& description, ErrorMessage* error_message) {
|
| + error_message->set_code(error_code);
|
| + error_message->set_description(description);
|
| +}
|
| +
|
| +void UnitTestBase::InitInvalidationMessage(const vector<InvalidationP>& invs,
|
| + InvalidationMessage *inv_message) {
|
| + for (size_t i = 0; i < invs.size(); ++i) {
|
| + inv_message->add_invalidation()->CopyFrom(invs[i]);
|
| + }
|
| +}
|
| +
|
| +TimeDelta UnitTestBase::EndOfTestWaitTime() {
|
| + return TimeDelta::FromSeconds(50);
|
| +}
|
| +
|
| +TimeDelta UnitTestBase::MessageHandlingDelay() {
|
| + return TimeDelta::FromMilliseconds(50);
|
| +}
|
| +
|
| +void UnitTestBase::InitTestObjectIds(int count, vector<ObjectIdP>* object_ids) {
|
| + for (int i = 0; i < count; ++i) {
|
| + ObjectIdP object_id;
|
| + object_id.set_source(ObjectSource_Type_TEST);
|
| + object_id.set_name(StringPrintf("oid%d", i));
|
| + object_ids->push_back(object_id);
|
| + }
|
| +}
|
| +
|
| +void UnitTestBase::ConvertFromObjectIdProtos(
|
| + const vector<ObjectIdP>& oid_protos, vector<ObjectId> *oids) {
|
| + for (size_t i = 0; i < oid_protos.size(); ++i) {
|
| + ObjectId object_id;
|
| + ProtoConverter::ConvertFromObjectIdProto(oid_protos[i], &object_id);
|
| + oids->push_back(object_id);
|
| + }
|
| +}
|
| +
|
| +void UnitTestBase::ConvertFromInvalidationProtos(
|
| + const vector<InvalidationP>& inv_protos, vector<Invalidation> *invs) {
|
| + for (size_t i = 0; i < inv_protos.size(); ++i) {
|
| + Invalidation inv;
|
| + ProtoConverter::ConvertFromInvalidationProto(inv_protos[i], &inv);
|
| + invs->push_back(inv);
|
| + }
|
| +}
|
| +
|
| +void UnitTestBase::MakeInvalidationsFromObjectIds(
|
| + const vector<ObjectIdP>& object_ids,
|
| + vector<InvalidationP>* invalidations) {
|
| + for (size_t i = 0; i < object_ids.size(); ++i) {
|
| + InvalidationP invalidation;
|
| + invalidation.mutable_object_id()->CopyFrom(object_ids[i]);
|
| + invalidation.set_is_known_version(true);
|
| + invalidation.set_is_trickle_restart(true);
|
| +
|
| + // Pick an arbitrary version number; it shouldn't really matter, but we
|
| + // try not to make them correlated too much with the object name.
|
| + invalidation.set_version(100 + ((i * 19) % 31));
|
| + invalidations->push_back(invalidation);
|
| + }
|
| +}
|
| +
|
| +void UnitTestBase::MakeRegistrationStatusesFromObjectIds(
|
| + const vector<ObjectIdP>& object_ids, bool is_reg, bool is_success,
|
| + vector<RegistrationStatus>* registration_statuses) {
|
| + for (size_t i = 0; i < object_ids.size(); ++i) {
|
| + RegistrationStatus registration_status;
|
| + registration_status.mutable_registration()->mutable_object_id()->CopyFrom(
|
| + object_ids[i]);
|
| + registration_status.mutable_registration()->set_op_type(
|
| + is_reg ? RegistrationP::REGISTER : RegistrationP::UNREGISTER);
|
| + registration_status.mutable_status()->set_code(
|
| + is_success ? StatusP::SUCCESS : StatusP::TRANSIENT_FAILURE);
|
| + registration_statuses->push_back(registration_status);
|
| + }
|
| +}
|
| +
|
| +TimeDelta UnitTestBase::GetMaxDelay(int delay_ms) {
|
| + int64 extra_delay_ms = (delay_ms * kDefaultSmearPercent) / 100.0;
|
| + return TimeDelta::FromMilliseconds(extra_delay_ms + delay_ms);
|
| +}
|
| +
|
| +TimeDelta UnitTestBase::GetMaxBatchingDelay(
|
| + const ProtocolHandlerConfigP& config) {
|
| + return GetMaxDelay(config.batching_delay_ms());
|
| +}
|
| +
|
| +void UnitTestBase::InitZeroRegistrationSummary(RegistrationSummary* summary) {
|
| + summary->set_num_registrations(0);
|
| + // "\3329..." can trigger MSVC to warn about "octal escape sequence terminated
|
| + // by decimal number", so break the string between the two to avoid the
|
| + // warning.
|
| + string zero_digest(
|
| + "\332" "9\243\356^kK\r2U\277\357\225`\030\220\257\330\007\t");
|
| + summary->set_registration_digest(zero_digest);
|
| +}
|
| +
|
| +void UnitTestBase::InitServerHeader(const string& token, ServerHeader* header) {
|
| + ProtoHelpers::InitProtocolVersion(header->mutable_protocol_version());
|
| + header->set_client_token(token);
|
| + if (reg_summary.get() != NULL) {
|
| + header->mutable_registration_summary()->CopyFrom(*reg_summary.get());
|
| + }
|
| +
|
| + // Use arbitrary server time and message id, since they don't matter.
|
| + header->set_server_time_ms(314159265);
|
| + header->set_message_id("message-id-for-test");
|
| +}
|
| +
|
| +bool UnitTestBase::CompareMessages(
|
| + const ::google::protobuf::MessageLite& expected,
|
| + const ::google::protobuf::MessageLite& actual) {
|
| + // TODO: Fill in proper implementation.
|
| + return true;
|
| +}
|
| +
|
| +void UnitTestBase::ProcessIncomingMessage(const ServerToClientMessage& message,
|
| + TimeDelta delay) {
|
| + string serialized;
|
| + message.SerializeToString(&serialized);
|
| + message_callback->Run(serialized);
|
| + internal_scheduler->PassTime(delay);
|
| +}
|
| +
|
| +Matcher<ClientHeader> UnitTestBase::ClientHeaderMatches(
|
| + const ClientHeader* header) {
|
| + return AllOf(Property(&ClientHeader::protocol_version,
|
| + EqualsProto(header->protocol_version())),
|
| + Property(&ClientHeader::registration_summary,
|
| + EqualsProto(header->registration_summary())),
|
| + Property(&ClientHeader::max_known_server_time_ms,
|
| + header->max_known_server_time_ms()),
|
| + Property(&ClientHeader::message_id,
|
| + header->message_id()));
|
| +}
|
| +
|
| +} // namespace invalidation
|
|
|