| Index: third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.h
|
| diff --git a/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.h b/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4c5580361408475c6c13ad59ede02cba5e88d8b0
|
| --- /dev/null
|
| +++ b/third_party/cacheinvalidation/src/google/cacheinvalidation/test/test-utils.h
|
| @@ -0,0 +1,320 @@
|
| +// 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, a
|
| +// mock storage layer, and a mock listener.
|
| +
|
| +#ifndef GOOGLE_CACHEINVALIDATION_TEST_TEST_UTILS_H_
|
| +#define GOOGLE_CACHEINVALIDATION_TEST_TEST_UTILS_H_
|
| +
|
| +#include "google/cacheinvalidation/client_protocol.pb.h"
|
| +#include "google/cacheinvalidation/include/invalidation-listener.h"
|
| +#include "google/cacheinvalidation/include/types.h"
|
| +#include "google/cacheinvalidation/types.pb.h"
|
| +#include "google/cacheinvalidation/deps/gmock.h"
|
| +#include "google/cacheinvalidation/deps/string_util.h"
|
| +#include "google/cacheinvalidation/impl/basic-system-resources.h"
|
| +#include "google/cacheinvalidation/impl/constants.h"
|
| +#include "google/cacheinvalidation/impl/log-macro.h"
|
| +#include "google/cacheinvalidation/impl/protocol-handler.h"
|
| +#include "google/cacheinvalidation/impl/statistics.h"
|
| +#include "google/cacheinvalidation/test/deterministic-scheduler.h"
|
| +
|
| +namespace invalidation {
|
| +
|
| +using ::ipc::invalidation::ObjectSource_Type_TEST;
|
| +using ::ipc::invalidation::ClientHeader;
|
| +using ::ipc::invalidation::ClientVersion;
|
| +using ::ipc::invalidation::InvalidationP;
|
| +using ::ipc::invalidation::ObjectIdP;
|
| +using ::ipc::invalidation::ProtocolVersion;
|
| +using ::ipc::invalidation::RegistrationP_OpType_REGISTER;
|
| +using ::ipc::invalidation::RegistrationP_OpType_UNREGISTER;
|
| +using ::ipc::invalidation::RegistrationStatus;
|
| +using ::ipc::invalidation::RegistrationSummary;
|
| +using ::ipc::invalidation::ServerHeader;
|
| +using ::ipc::invalidation::ServerToClientMessage;
|
| +using ::ipc::invalidation::StatusP_Code_SUCCESS;
|
| +using ::ipc::invalidation::Version;
|
| +using ::google::protobuf::MessageLite;
|
| +using ::testing::_;
|
| +using ::testing::EqualsProto;
|
| +using ::testing::Matcher;
|
| +using ::testing::Property;
|
| +using ::testing::SaveArg;
|
| +using ::testing::StrictMock;
|
| +
|
| +/* A random class whose RandDouble method always returns a given constant. */
|
| +class FakeRandom : public Random {
|
| + public:
|
| + // Constructs a fake random generator that always returns |return_value|,
|
| + // which must be in the range [0, 1).
|
| + explicit FakeRandom(double return_value)
|
| + : Random(0), return_value_(return_value) {
|
| + CHECK_GE(return_value_, 0.0);
|
| + CHECK_LT(return_value_, 1.0);
|
| + }
|
| +
|
| + virtual ~FakeRandom() {}
|
| +
|
| + virtual double RandDouble() {
|
| + return return_value_;
|
| + }
|
| +
|
| + private:
|
| + double return_value_;
|
| +};
|
| +
|
| +// A mock of the Scheduler interface.
|
| +class MockScheduler : public Scheduler {
|
| + public:
|
| + MOCK_METHOD2(Schedule, void(TimeDelta, Closure*)); // NOLINT
|
| + MOCK_CONST_METHOD0(IsRunningOnThread, bool());
|
| + MOCK_CONST_METHOD0(GetCurrentTime, Time());
|
| + MOCK_METHOD1(SetSystemResources, void(SystemResources*)); // NOLINT
|
| +};
|
| +
|
| +// A mock of the Network interface.
|
| +class MockNetwork : public NetworkChannel {
|
| + public:
|
| + MOCK_METHOD1(SendMessage, void(const string&)); // NOLINT
|
| + MOCK_METHOD1(SetMessageReceiver, void(MessageCallback*)); // NOLINT
|
| + MOCK_METHOD1(AddNetworkStatusReceiver, void(NetworkStatusCallback*)); // NOLINT
|
| + MOCK_METHOD1(SetSystemResources, void(SystemResources*)); // NOLINT
|
| +};
|
| +
|
| +// A mock of the Storage interface.
|
| +class MockStorage : public Storage {
|
| + public:
|
| + MOCK_METHOD3(WriteKey, void(const string&, const string&, WriteKeyCallback*)); // NOLINT
|
| + MOCK_METHOD2(ReadKey, void(const string&, ReadKeyCallback*)); // NOLINT
|
| + MOCK_METHOD2(DeleteKey, void(const string&, DeleteKeyCallback*)); // NOLINT
|
| + MOCK_METHOD1(ReadAllKeys, void(ReadAllKeysCallback*)); // NOLINT
|
| + MOCK_METHOD1(SetSystemResources, void(SystemResources*)); // NOLINT
|
| +};
|
| +
|
| +// A mock of the InvalidationListener interface.
|
| +class MockInvalidationListener : public InvalidationListener {
|
| + public:
|
| + MOCK_METHOD1(Ready, void(InvalidationClient*)); // NOLINT
|
| +
|
| + MOCK_METHOD3(Invalidate,
|
| + void(InvalidationClient *, const Invalidation&, // NOLINT
|
| + const AckHandle&)); // NOLINT
|
| +
|
| + MOCK_METHOD3(InvalidateUnknownVersion,
|
| + void(InvalidationClient *, const ObjectId&,
|
| + const AckHandle&)); // NOLINT
|
| +
|
| + MOCK_METHOD2(InvalidateAll,
|
| + void(InvalidationClient *, const AckHandle&)); // NOLINT
|
| +
|
| + MOCK_METHOD3(InformRegistrationStatus,
|
| + void(InvalidationClient*, const ObjectId&, RegistrationState)); // NOLINT
|
| +
|
| + MOCK_METHOD4(InformRegistrationFailure,
|
| + void(InvalidationClient*, const ObjectId&, bool, const string&));
|
| +
|
| + MOCK_METHOD3(ReissueRegistrations,
|
| + void(InvalidationClient*, const string&, int));
|
| +
|
| + MOCK_METHOD2(InformError,
|
| + void(InvalidationClient*, const ErrorInfo&));
|
| +};
|
| +
|
| +// A base class for unit tests to share common methods and helper routines.
|
| +class UnitTestBase : public testing::Test {
|
| + public:
|
| + // Default smearing to be done to randomize delays. Zero to get
|
| + // precise delays.
|
| + static const int kDefaultSmearPercent = 0;
|
| +
|
| + // The token or nonce used by default for a client in client to server or
|
| + // server to client messages.
|
| + static const char *kClientToken;
|
| +
|
| + // When "waiting" at the end of a test to make sure nothing happens, how long
|
| + // to wait.
|
| + static TimeDelta EndOfTestWaitTime();
|
| +
|
| + // When "waiting" at the end of a test to make sure nothing happens, how long
|
| + // to wait. This delay will not only allow to run the processing on the
|
| + // workqueue but will also give some 'extra' time to the code to do other
|
| + // (incorrect) activities if there is a bug, e.g., make an uneccessary
|
| + // listener call, etc.
|
| + static TimeDelta MessageHandlingDelay();
|
| +
|
| + // Populates |object_ids| with |count| object ids in the TEST id space, each
|
| + // named oid<n>.
|
| + static void InitTestObjectIds(int count, vector<ObjectIdP>* object_ids);
|
| +
|
| + // Converts object id protos in |oid_protos| to ObjecIds in |oids|.
|
| + static void ConvertFromObjectIdProtos(const vector<ObjectIdP>& oid_protos,
|
| + vector<ObjectId> *oids);
|
| +
|
| + // Converts invalidation protos in |inv_protos| to Invalidations in |invs|.
|
| + static void ConvertFromInvalidationProtos(
|
| + const vector<InvalidationP>& inv_protos, vector<Invalidation> *invs);
|
| +
|
| + // For each object id in |object_ids|, adds an invalidation to |invalidations|
|
| + // for that object at an arbitrary version.
|
| + static void MakeInvalidationsFromObjectIds(
|
| + const vector<ObjectIdP>& object_ids,
|
| + vector<InvalidationP>* invalidations);
|
| +
|
| + // For each object in |object_ids|, makes a SUCCESSful registration status for
|
| + // that object, alternating between REGISTER and UNREGISTER. The precise
|
| + // contents of these messages are unimportant to the protocol handler; we just
|
| + // need them to pass the message validator.
|
| + static void MakeRegistrationStatusesFromObjectIds(
|
| + const vector<ObjectIdP>& object_ids, bool is_reg, bool is_success,
|
| + vector<RegistrationStatus>* registration_statuses);
|
| +
|
| + // Returns the maximum smeared delay possible for |delay_ms| given the
|
| + // |Smearer|'s default smearing.
|
| + static TimeDelta GetMaxDelay(int delay_ms);
|
| +
|
| + // Returns the maximum batching delay that a message will incur in the
|
| + // protocol handler.
|
| + static TimeDelta GetMaxBatchingDelay(const ProtocolHandlerConfigP& config);
|
| +
|
| + // Initializes |summary| with a registration summary for 0 objects.
|
| + static void InitZeroRegistrationSummary(RegistrationSummary* summary);
|
| +
|
| + // Creates a matcher for the parts of the header that the test can predict.
|
| + static Matcher<ClientHeader> ClientHeaderMatches(const ClientHeader* header);
|
| +
|
| + // Initialize |reg_message| to contain registrations for all objects in |oids|
|
| + // with |is_reg| indicating whether the operation is register or unregister.
|
| + static void InitRegistrationMessage(const vector<ObjectIdP>& oids,
|
| + bool is_reg, RegistrationMessage *reg_message);
|
| +
|
| + // Initializes |inv_message| to contain the invalidations |invs|.
|
| + static void InitInvalidationMessage(const vector<InvalidationP>& invs,
|
| + InvalidationMessage *inv_message);
|
| +
|
| + // Initializes |error_message| to contain given the |error_code| and error
|
| + // |description|.
|
| + static void InitErrorMessage(ErrorMessage::Code error_code,
|
| + const string& description, ErrorMessage* error_message);
|
| +
|
| + // Performs setup for protocol handler unit tests, e.g. creating resource
|
| + // components and setting up common expectations for certain mock objects.
|
| + virtual void SetUp();
|
| +
|
| + // Tears down the test, e.g., drains any schedulers if needed.
|
| + virtual void TearDown();
|
| +
|
| + // Initializes the basic system resources, using mocks for various components.
|
| + void InitSystemResources();
|
| +
|
| + // Sets up some common expectations for the system resources.
|
| + void InitCommonExpectations();
|
| +
|
| + // Initializes a server header with the given token (registration summary is
|
| + // picked up the internal state |reg_summary|).
|
| + void InitServerHeader(const string& token, ServerHeader* header);
|
| +
|
| + // Gives a ServerToClientMessage |message| to the protocol handler and
|
| + // passes time in the internal scheduler by |delay| waiting for processing to
|
| + // be done.
|
| + void ProcessIncomingMessage(const ServerToClientMessage& message,
|
| + TimeDelta delay);
|
| +
|
| + // Returns true iff the messages are equal (with lists interpreted as sets).
|
| + bool CompareMessages(
|
| + const ::google::protobuf::MessageLite& expected,
|
| + const ::google::protobuf::MessageLite& actual);
|
| +
|
| + // Checks that |vec1| and |vec2| contain the same number of elements
|
| + // and each element in |vec1| is present in |vec2| and vice-versa (Uses the
|
| + // == operator for comparing). Returns true iff it is the case. Note that this
|
| + // method will return true for (aab, abb)
|
| + template <class T>
|
| + static bool CompareVectorsAsSets(const vector<T>& vec1,
|
| + const vector<T>& vec2) {
|
| + if (vec1.size() != vec2.size()) {
|
| + return false;
|
| + }
|
| + for (size_t i = 0; i < vec1.size(); i++) {
|
| + bool found = false;
|
| + for (size_t j = 0; (j < vec2.size()) && !found; j++) {
|
| + found = found || (vec1[i] == vec2[j]);
|
| + }
|
| + if (!found) {
|
| + return false;
|
| + }
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + //
|
| + // Internal state
|
| + //
|
| +
|
| + // The time at which the test started. Initialized to an arbitrary value to
|
| + // ensure that we don't depend on it starting at 0.
|
| + Time start_time;
|
| +
|
| + // Components of BasicSystemResources. It takes ownership of all of these,
|
| + // and its destructor deletes them, so we need to create fresh ones for each
|
| + // test.
|
| +
|
| + // Use a deterministic scheduler for the protocol handler's internals, since
|
| + // we want precise control over when batching intervals expire.
|
| + DeterministicScheduler* internal_scheduler;
|
| +
|
| + // DeterministicScheduler or MockScheduler depending on the test.
|
| + MockScheduler* listener_scheduler;
|
| +
|
| + // Use a mock network to let us trap the protocol handler's message receiver
|
| + // and its attempts to send messages.
|
| + MockNetwork* network;
|
| +
|
| + // A logger.
|
| + Logger* logger;
|
| +
|
| + // Storage shouldn't be used by the protocol handler, so use a strict mock to
|
| + // catch any accidental calls.
|
| + MockStorage* storage;
|
| +
|
| + // System resources (owned by the test).
|
| + scoped_ptr<BasicSystemResources> resources;
|
| +
|
| + // Statistics object for counting occurrences of different types of events.
|
| + scoped_ptr<Statistics> statistics;
|
| +
|
| + // Message callback installed by the protocol handler. Captured by the mock
|
| + // network.
|
| + MessageCallback* message_callback;
|
| +
|
| + // Registration summary to be placed in messages from the client to the server
|
| + // and vice-versa.
|
| + scoped_ptr<RegistrationSummary> reg_summary;
|
| +};
|
| +
|
| +// Creates an action InvokeAndDeleteClosure<k> that invokes the kth closure and
|
| +// deletes it after the Run method has been called.
|
| +ACTION_TEMPLATE(
|
| + InvokeAndDeleteClosure,
|
| + HAS_1_TEMPLATE_PARAMS(int, k),
|
| + AND_0_VALUE_PARAMS()) {
|
| + std::tr1::get<k>(args)->Run();
|
| + delete std::tr1::get<k>(args);
|
| +}
|
| +
|
| +} // namespace invalidation
|
| +
|
| +#endif // GOOGLE_CACHEINVALIDATION_TEST_TEST_UTILS_H_
|
|
|