Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ members = [
"tests/crypto-providers/test-storage",
"tests/dns",
"tests/endurance",
"tests/enums-query-parameters",
"tests/integration",
"tests/integration-auth",
"tests/o11y",
Expand Down Expand Up @@ -472,6 +473,9 @@ language = { default-features = false, version = "1", pat
google-cloud-dns-v1 = { default-features = false, path = "src/generated/cloud/dns/v1" }
google-cloud-showcase-v1beta1 = { default-features = false, path = "src/generated/showcase" }
google-cloud-trace-v1 = { default-features = false, path = "src/generated/devtools/cloudtrace/v1" }
# The names on these are too long, I do not want to reformat the whole file for them.
google-cloud-workflows-v1 = { default-features = false, path = "src/generated/cloud/workflows/v1" }
google-cloud-workflows-executions-v1 = { default-features = false, path = "src/generated/cloud/workflows/executions/v1" }

# Local test packages (never add a version)
google-cloud-test-utils = { default-features = false, path = "src/test-utils" }
Expand Down
32 changes: 30 additions & 2 deletions src/test-utils/src/resource_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

use rand::{
Rng,
distr::{Distribution, Uniform},
distr::{Alphanumeric, Distribution, Uniform},
};

/// A common prefix for resource ids.
Expand All @@ -26,12 +26,24 @@ pub const PREFIX: &str = "rust-sdk-testing-";

const BUCKET_ID_LENGTH: usize = 63;

/// Generate a random bucket id
const WORKFLOW_ID_LENGTH: usize = 64;

/// Generate a random bucket id.
pub fn random_bucket_id() -> String {
let id = LowercaseAlphanumeric.random_string(BUCKET_ID_LENGTH - PREFIX.len());
format!("{PREFIX}{id}")
}

/// Generate a random workflow id.
pub fn random_workflow_id() -> String {
let id: String = rand::rng()
.sample_iter(&Alphanumeric)
.take(WORKFLOW_ID_LENGTH - PREFIX.len())
.map(char::from)
.collect();
format!("{PREFIX}{id}")
}

const LOWERCASE_ALPHANUMERIC_CHARSET: &[u8] = b"abcdefghijklmnopqrstuvwxyz0123456789";

/// Sample a `u8`, uniformly distributed over ASCII lowercase letters and numbers: a-z and 0-9.
Expand Down Expand Up @@ -83,6 +95,22 @@ mod tests {
assert!(test.is_ok(), "{test:?}");
}

#[test]
fn workflow_id() {
let got = random_workflow_id();
assert!(
got.len() <= WORKFLOW_ID_LENGTH,
"{got} has more than {WORKFLOW_ID_LENGTH} characters"
);
let suffix = got
.strip_prefix(PREFIX)
.expect("{got} should start with {PREFIX}");
assert!(
suffix.chars().all(|c| c.is_alphanumeric()),
"the suffix should be alphanumeric: {suffix}"
);
}

#[test]
fn lowercase() {
let got: String = rand::rng()
Expand Down
39 changes: 39 additions & 0 deletions tests/enums-query-parameters/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2026 Google LLC
#
# 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
#
# https://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.

[package]
description = "Integration tests for enums in query parameters."
edition.workspace = true
name = "integration-tests-enums-query-parameters"
publish = false
version = "0.0.0"

[features]
# These are normally disabled because they run against production.
run-integration-tests = []
# Logging enables more verbose output for the tests.
log-integration-tests = []

[dependencies]
anyhow.workspace = true
chrono = { workspace = true, features = ["now"] }
futures.workspace = true
google-cloud-workflows-v1 = { workspace = true, features = ["default"] }
google-cloud-workflows-executions-v1 = { workspace = true, features = ["default"] }
google-cloud-gax.workspace = true
google-cloud-test-utils = { workspace = true }
google-cloud-lro.workspace = true
tokio.workspace = true
tracing.workspace = true
tracing-subscriber = { workspace = true, features = ["fmt"] }
6 changes: 6 additions & 0 deletions tests/enums-query-parameters/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Integration tests for enum query parameters

This is an integration test for enum values in query parameters. We use the
`google-cloud-workflow-executions-v1` library because it uses the feature. We
also use the `google-cloud-workflow-v1` library to create data (workflow
executions) for the tests.
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,32 @@
// limitations under the License.

use anyhow::Result;
use gax::exponential_backoff::{ExponentialBackoff, ExponentialBackoffBuilder};
use gax::options::RequestOptionsBuilder;
use gax::paginator::ItemPaginator as _;
use gax::retry_policy::{AlwaysRetry, RetryPolicyExt};
use google_cloud_gax::exponential_backoff::{ExponentialBackoff, ExponentialBackoffBuilder};
use google_cloud_gax::options::RequestOptionsBuilder;
use google_cloud_gax::paginator::ItemPaginator as _;
use google_cloud_gax::retry_policy::{AlwaysRetry, RetryPolicyExt};
use google_cloud_lro::Poller;
use google_cloud_test_utils::resource_names::random_workflow_id;
use google_cloud_test_utils::runtime_config::{project_id, region_id, test_service_account};
use lro::Poller;
use google_cloud_workflows_executions_v1::{
client::Executions, model::Execution, model::ExecutionView,
};
use google_cloud_workflows_v1::{client::Workflows, model::Workflow, model::workflow::SourceCode};
use std::time::Duration;

// Verify enum query parameters are serialized correctly.
pub async fn list() -> Result<()> {
pub async fn run() -> Result<()> {
// Create a workflow so we can list its executions. We rely on the other
// workflows integration tests to delete it if something fails or crashes
// in this test.
let parent = create_test_workflow().await?;
let client = wfe::client::Executions::builder()
.with_tracing()
.build()
.await?;
let client = Executions::builder().with_tracing().build().await?;

// Create an execution with a label. The label is not returned for the `BASIC` view.
let start = client
.create_execution()
.set_parent(&parent)
.set_execution(wfe::model::Execution::new().set_labels([("test-label", "test-value")]))
.set_execution(Execution::new().set_labels([("test-label", "test-value")]))
.send()
.await?;
tracing::info!("start was successful={start:?}");
Expand All @@ -45,7 +47,7 @@ pub async fn list() -> Result<()> {
let mut executions = client
.list_executions()
.set_parent(&parent)
.set_view(wfe::model::ExecutionView::Basic)
.set_view(ExecutionView::Basic)
.by_item();

while let Some(execution) = executions.next().await {
Expand All @@ -58,7 +60,7 @@ pub async fn list() -> Result<()> {
let mut executions = client
.list_executions()
.set_parent(&parent)
.set_view(wfe::model::ExecutionView::Full)
.set_view(ExecutionView::Full)
.by_item();

while let Some(execution) = executions.next().await {
Expand Down Expand Up @@ -93,16 +95,16 @@ main:
- sayHello:
return: Hello World
"###;
let source_code = wf::model::workflow::SourceCode::SourceContents(source_contents.to_string());
let workflow_id = crate::random_workflow_id();
let source_code = SourceCode::SourceContents(source_contents.to_string());
let workflow_id = random_workflow_id();

tracing::info!("Start create_workflow() LRO and poll it to completion");
let response = client
.create_workflow()
.set_parent(format!("projects/{project_id}/locations/{location_id}"))
.set_workflow_id(&workflow_id)
.set_workflow(
wf::model::Workflow::new()
Workflow::new()
.set_labels([("integration-test", "true")])
.set_service_account(&workflows_runner)
.set_source_code(source_code),
Expand All @@ -116,8 +118,8 @@ main:
Ok(response.name)
}

async fn workflow_client() -> Result<wf::client::Workflows> {
let client = wf::client::Workflows::builder()
async fn workflow_client() -> Result<Workflows> {
let client = Workflows::builder()
.with_retry_policy(
AlwaysRetry
.with_time_limit(Duration::from_secs(15))
Expand Down
21 changes: 21 additions & 0 deletions tests/enums-query-parameters/tests/driver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2026 Google LLC
//
// 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
//
// https://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.

#[cfg(all(test, feature = "run-integration-tests"))]
mod enums_query_parameters {
#[tokio::test]
async fn run() -> anyhow::Result<()> {
integration_tests_enums_query_parameters::run().await
}
}
4 changes: 0 additions & 4 deletions tests/integration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,6 @@ path = "../../src/generated/cloud/telcoautomation/v1"
package = "google-cloud-workflows-v1"
path = "../../src/generated/cloud/workflows/v1"

[dependencies.wfe]
package = "google-cloud-workflows-executions-v1"
path = "../../src/generated/cloud/workflows/executions/v1"

[dev-dependencies]
anyhow.workspace = true
httptest.workspace = true
Expand Down
17 changes: 1 addition & 16 deletions tests/integration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

use google_cloud_test_utils::resource_names::LowercaseAlphanumeric;
use google_cloud_test_utils::resource_names::random_bucket_id;
use rand::{Rng, distr::Alphanumeric};
pub(crate) use google_cloud_test_utils::resource_names::random_workflow_id;

pub type Result<T> = anyhow::Result<T>;
pub mod aiplatform;
Expand All @@ -26,32 +26,17 @@ pub mod secret_manager;
pub mod showcase;
pub mod storage;
pub mod workflows;
pub mod workflows_executions;

pub const SECRET_ID_LENGTH: usize = 64;

pub const VM_ID_LENGTH: usize = 63;

pub const WORKFLOW_ID_LENGTH: usize = 64;

pub fn report_error(e: anyhow::Error) -> anyhow::Error {
eprintln!("\n\nERROR {e:?}\n");
tracing::error!("ERROR {e:?}");
e
}

pub(crate) fn random_workflow_id() -> String {
// Workflow ids must start with a letter, we use `wf-` as a prefix to
// meet this requirement.
const PREFIX: &str = "wf-";
let workflow_id: String = rand::rng()
.sample_iter(&Alphanumeric)
.take(WORKFLOW_ID_LENGTH - PREFIX.len())
.map(char::from)
.collect();
format!("{PREFIX}{workflow_id}")
}

pub(crate) fn random_image_name() -> String {
const PREFIX: &str = "img-";
let image_id = LowercaseAlphanumeric.random_string(VM_ID_LENGTH - PREFIX.len());
Expand Down
8 changes: 0 additions & 8 deletions tests/integration/tests/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,12 +329,4 @@ mod driver {
.await
.map_err(integration_tests::report_error)
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn workflows_executions() -> integration_tests::Result<()> {
let _guard = enable_tracing();
integration_tests::workflows_executions::list()
.await
.map_err(integration_tests::report_error)
}
}
Loading