blob: 3dadf4f25fa139234e88d7a2f669f66cda313f2f [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_CRONET_NATIVE_TEST_TEST_URL_REQUEST_CALLBACK_H_
#define COMPONENTS_CRONET_NATIVE_TEST_TEST_URL_REQUEST_CALLBACK_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "cronet_c.h"
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
namespace cronet {
// Various test utility functions for testing Cronet.
namespace test {
class TestUrlRequestCallback {
public:
enum ResponseStep {
NOTHING,
ON_RECEIVED_REDIRECT,
ON_RESPONSE_STARTED,
ON_READ_COMPLETED,
ON_SUCCEEDED,
ON_FAILED,
ON_CANCELED,
};
enum FailureType {
NONE,
CANCEL_SYNC,
CANCEL_ASYNC,
// Same as above, but continues to advance the request after posting
// the cancellation task.
CANCEL_ASYNC_WITHOUT_PAUSE,
};
class UrlResponseInfo {
public:
// Construct actual response info copied from Cronet_UrlResponseInfoPtr.
explicit UrlResponseInfo(Cronet_UrlResponseInfoPtr response_info);
// Construct expected response info for testing.
UrlResponseInfo(const std::vector<std::string>& urls,
const std::string& message,
int32_t status_code,
int64_t received_bytes,
std::vector<std::string> headers);
~UrlResponseInfo();
// Data copied from response_info to make it available after request is
// done.
std::string url;
std::vector<std::string> url_chain;
int32_t http_status_code = 0;
std::string http_status_text;
std::vector<std::pair<std::string, std::string>> all_headers;
bool was_cached = false;
std::string negotiated_protocol;
std::string proxy_server;
int64_t received_byte_count = 0;
};
std::vector<std::unique_ptr<UrlResponseInfo>> redirect_response_info_list_;
std::vector<std::string> redirect_url_list_;
std::unique_ptr<UrlResponseInfo> response_info_;
// Owned by UrlRequest, only valid until UrlRequest is destroyed.
Cronet_ErrorPtr last_error_ = nullptr;
// Values copied from |last_error_| valid after UrlRequest is destroyed.
Cronet_Error_ERROR_CODE last_error_code_ =
Cronet_Error_ERROR_CODE_ERROR_OTHER;
std::string last_error_message_;
ResponseStep response_step_ = NOTHING;
int redirect_count_ = 0;
bool on_error_called_ = false;
bool on_canceled_called_ = false;
int response_data_length_ = 0;
std::string response_as_string_;
explicit TestUrlRequestCallback(bool direct_executor);
virtual ~TestUrlRequestCallback();
Cronet_ExecutorPtr GetExecutor();
Cronet_UrlRequestCallbackPtr CreateUrlRequestCallback();
void set_auto_advance(bool auto_advance) { auto_advance_ = auto_advance; }
void set_accumulate_response_data(bool accuumulate) {
accumulate_response_data_ = accuumulate;
}
void set_failure(FailureType failure_type, ResponseStep failure_step) {
failure_step_ = failure_step;
failure_type_ = failure_type;
}
void WaitForDone() { done_.Wait(); }
void WaitForNextStep() {
step_block_.Wait();
step_block_.Reset();
}
void ShutdownExecutor();
bool IsDone() { return done_.IsSignaled(); }
protected:
class Executor;
virtual void OnRedirectReceived(Cronet_UrlRequestPtr request,
Cronet_UrlResponseInfoPtr info,
Cronet_String newLocationUrl);
virtual void OnResponseStarted(Cronet_UrlRequestPtr request,
Cronet_UrlResponseInfoPtr info);
virtual void OnReadCompleted(Cronet_UrlRequestPtr request,
Cronet_UrlResponseInfoPtr info,
Cronet_BufferPtr buffer,
uint64_t bytes_read);
virtual void OnSucceeded(Cronet_UrlRequestPtr request,
Cronet_UrlResponseInfoPtr info);
virtual void OnFailed(Cronet_UrlRequestPtr request,
Cronet_UrlResponseInfoPtr info,
Cronet_ErrorPtr error);
virtual void OnCanceled(Cronet_UrlRequestPtr request,
Cronet_UrlResponseInfoPtr info);
void StartNextRead(Cronet_UrlRequestPtr request) {
Cronet_BufferPtr buffer = Cronet_Buffer_Create();
Cronet_Buffer_InitWithAlloc(buffer, READ_BUFFER_SIZE);
StartNextRead(request, buffer);
}
void StartNextRead(Cronet_UrlRequestPtr request, Cronet_BufferPtr buffer) {
Cronet_UrlRequest_Read(request, buffer);
}
void SignalDone() { done_.Signal(); }
void CheckExecutorThread();
/**
* Returns false if the callback should continue to advance the
* request.
*/
bool MaybeCancelOrPause(Cronet_UrlRequestPtr request);
// Implementation of Cronet_UrlRequestCallback methods.
static TestUrlRequestCallback* GetThis(Cronet_UrlRequestCallbackPtr self);
static void OnRedirectReceived(Cronet_UrlRequestCallbackPtr self,
Cronet_UrlRequestPtr request,
Cronet_UrlResponseInfoPtr info,
Cronet_String newLocationUrl);
static void OnResponseStarted(Cronet_UrlRequestCallbackPtr self,
Cronet_UrlRequestPtr request,
Cronet_UrlResponseInfoPtr info);
static void OnReadCompleted(Cronet_UrlRequestCallbackPtr self,
Cronet_UrlRequestPtr request,
Cronet_UrlResponseInfoPtr info,
Cronet_BufferPtr buffer,
uint64_t bytesRead);
static void OnSucceeded(Cronet_UrlRequestCallbackPtr self,
Cronet_UrlRequestPtr request,
Cronet_UrlResponseInfoPtr info);
static void OnFailed(Cronet_UrlRequestCallbackPtr self,
Cronet_UrlRequestPtr request,
Cronet_UrlResponseInfoPtr info,
Cronet_ErrorPtr error);
static void OnCanceled(Cronet_UrlRequestCallbackPtr self,
Cronet_UrlRequestPtr request,
Cronet_UrlResponseInfoPtr info);
// Implementation of Cronet_Executor methods.
static void Execute(Cronet_ExecutorPtr self, Cronet_RunnablePtr runnable);
static void ExecuteDirect(Cronet_ExecutorPtr self,
Cronet_RunnablePtr runnable);
const int READ_BUFFER_SIZE = 32 * 1024;
// When false, the consumer is responsible for all calls into the request
// that advance it.
bool auto_advance_ = true;
// When false response data is not accuumulated for better performance.
bool accumulate_response_data_ = true;
// Whether to create direct executors.
const bool direct_executor_;
// Conditionally fail on certain steps.
FailureType failure_type_ = NONE;
ResponseStep failure_step_ = NOTHING;
// Signals when request is done either successfully or not.
base::WaitableEvent done_;
// Signaled on each step when |auto_advance_| is false.
base::WaitableEvent step_block_;
// Lock that synchronizes access to |executor_| and |executor_thread_|.
base::Lock executor_lock_;
// Executor that runs callback tasks.
Cronet_ExecutorPtr executor_ = nullptr;
// Thread on which |executor_| runs callback tasks.
std::unique_ptr<base::Thread> executor_thread_;
};
} // namespace test
} // namespace cronet
#endif // COMPONENTS_CRONET_NATIVE_TEST_TEST_URL_REQUEST_CALLBACK_H_