use super::dispatcher::Dispatcher;
use super::format::Arrow;
use super::pool::{StreamPool, StreamPoolOptions};
use super::retry_policy::RetryOptions;
use super::runner::WriteRequest;
use super::transport::Transport;
use crate::google::cloud::bigquery::storage::v1::append_rows_request::{ArrowData, Rows};
use crate::google::cloud::bigquery::storage::v1::append_rows_response::{AppendResult, Response};
use crate::google::cloud::bigquery::storage::v1::{AppendRowsRequest, AppendRowsResponse};
use crate::model::{ArrowRecordBatch, ArrowSchema, ProtoSchema};
use bigquery_grpc_mock::google::cloud::bigquery::storage::v1;
use bytes::Bytes;
use google_cloud_auth::credentials::anonymous::Builder as Anonymous;
use google_cloud_gax::backoff_policy::BackoffPolicy;
use google_cloud_gax::retry_policy::NeverRetry;
use google_cloud_gax::retry_state::RetryState;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::mpsc;
mockall::mock! {
#[derive(Debug)]
pub BackoffPolicy {}
impl BackoffPolicy for BackoffPolicy {
fn on_failure(&self, state: &RetryState) -> Duration;
}
}
#[derive(Debug)]
pub(super) struct NoBackoff;
impl BackoffPolicy for NoBackoff {
fn on_failure(&self, _state: &RetryState) -> Duration {
Duration::ZERO
}
}
pub(super) fn write_stream() -> String {
"projects/p/datasets/d/tables/t/streams/s".to_string()
}
pub(super) fn format() -> Arrow {
Arrow { schema: schema() }
}
pub(super) fn rows(id: i64) -> ArrowRecordBatch {
ArrowRecordBatch::new().set_serialized_record_batch(id.to_string())
}
pub(super) fn schema() -> ArrowSchema {
ArrowSchema::new().set_serialized_schema("test")
}
pub(super) fn proto_schema() -> ProtoSchema {
let descriptor = wkt::DescriptorProto::default().set_name("TestMessage".to_string());
ProtoSchema::new().set_proto_descriptor(descriptor)
}
pub(super) async fn test_transport<T: Into<String>>(endpoint: T) -> anyhow::Result<Transport> {
let mut config = gaxi::options::ClientConfig::default();
config.cred = Some(Anonymous::new().build());
config.endpoint = Some(endpoint.into());
Ok(Transport::new(config).await?)
}
pub(super) fn convert(pb: &AppendRowsResponse) -> v1::AppendRowsResponse {
use prost::Message;
let v = pb.encode_to_vec();
v1::AppendRowsResponse::decode(v.as_slice()).expect("encoding is always valid.")
}
pub(super) fn test_request(index: i64) -> AppendRowsRequest {
use crate::google::cloud::bigquery::storage::v1::{ArrowRecordBatch, ArrowSchema};
AppendRowsRequest {
write_stream: "projects/p/datasets/d/tables/t/streams/s".to_string(),
offset: Some(index),
rows: Some(Rows::ArrowRows(ArrowData {
writer_schema: Some(ArrowSchema {
serialized_schema: Bytes::from_static(b"test-schema"),
}),
rows: Some(ArrowRecordBatch {
serialized_record_batch: Bytes::from_static(b"test-rows"),
..Default::default()
}),
})),
..Default::default()
}
}
pub(super) fn test_response(index: i64) -> AppendRowsResponse {
AppendRowsResponse {
response: Some(Response::AppendResult(AppendResult {
offset: Some(index),
})),
write_stream: "projects/p/datasets/d/tables/t/streams/s".to_string(),
..Default::default()
}
}
pub(super) fn test_retry_options() -> RetryOptions {
RetryOptions {
retry_policy: Arc::new(NeverRetry),
backoff_policy: Arc::new(NoBackoff),
attempt_timeout: None,
}
}
pub(super) async fn test_dispatcher(
req_tx: mpsc::UnboundedSender<WriteRequest>,
) -> anyhow::Result<Arc<Dispatcher>> {
let transport = Arc::new(test_transport("http://ignored:1").await?);
let pool = Arc::new(StreamPool::new(transport, StreamPoolOptions::default()));
pool.seed([0]);
pool.lock()
.first_mut()
.expect("there is one entry in the pool")
.req_tx = req_tx;
let dispatcher = Arc::new(Dispatcher::new(pool, test_retry_options()));
Ok(dispatcher)
}