Skip to content

Commit 576ab46

Browse files
authored
test(pubub): add cleanup for topics (#3363)
Cleanup stale topics created by integration tests. Pubsub topics don't have a create time field, so instead create a label that records the creation time. There are restrictions on the characters used in labels including no uppercase letters. The wkt::Timestamp serialization uses uppercase letters, so instead this keeps it simple for the tests and stores the time in seconds.
1 parent 355c5ba commit 576ab46

File tree

3 files changed

+58
-7
lines changed

3 files changed

+58
-7
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/integration-tests/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ run-showcase-tests = []
3030
[dependencies]
3131
anyhow.workspace = true
3232
bytes.workspace = true
33+
chrono = { workspace = true, features = ["now"] }
3334
crc32c.workspace = true
3435
futures.workspace = true
3536
auth.workspace = true

src/integration-tests/src/pubsub.rs

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use crate::{Error, Result};
16+
17+
use gax::paginator::ItemPaginator as _;
1518
use pubsub::{client::TopicAdmin, model::Topic};
1619
use rand::{Rng, distr::Alphanumeric};
1720

18-
use crate::Result;
19-
2021
pub async fn basic_topic() -> Result<()> {
2122
// Enable a basic subscriber. Useful to troubleshoot problems and visually
2223
// verify tracing is doing something.
@@ -43,7 +44,7 @@ pub async fn basic_topic() -> Result<()> {
4344
tracing::info!("success with get_topic={get_topic:?}");
4445
assert_eq!(get_topic.name, topic.name);
4546

46-
cleanup_test_topic(client, topic.name).await?;
47+
cleanup_test_topic(&client, topic.name).await?;
4748

4849
Ok(())
4950
}
@@ -61,28 +62,76 @@ fn random_topic_name(project: String) -> String {
6162
}
6263

6364
pub async fn create_test_topic() -> Result<(TopicAdmin, Topic)> {
64-
let project = crate::project_id()?;
65+
let project_id = crate::project_id()?;
6566
let client = pubsub::client::TopicAdmin::builder()
6667
.with_tracing()
6768
.build()
6869
.await?;
69-
let topic_name = random_topic_name(project);
70+
71+
cleanup_stale_topics(&client, &project_id).await?;
72+
73+
let topic_name = random_topic_name(project_id);
74+
let now = chrono::Utc::now().timestamp().to_string();
7075

7176
tracing::info!("testing create_topic()");
7277
let topic = client
7378
.create_topic()
7479
.set_name(topic_name)
75-
.set_labels([("integration-test", "true")])
80+
.set_labels([("integration-test", "true"), ("create-time", &now)])
7681
.send()
7782
.await?;
7883
tracing::info!("success on create_topic: {topic:?}");
7984

8085
Ok((client, topic))
8186
}
8287

83-
pub async fn cleanup_test_topic(client: TopicAdmin, topic_name: String) -> Result<()> {
88+
pub async fn cleanup_test_topic(client: &TopicAdmin, topic_name: String) -> Result<()> {
8489
tracing::info!("testing delete_topic()");
8590
client.delete_topic().set_topic(topic_name).send().await?;
8691
tracing::info!("success on delete_topic");
8792
Ok(())
8893
}
94+
95+
pub async fn cleanup_stale_topics(client: &TopicAdmin, project_id: &str) -> Result<()> {
96+
let stale_deadline = chrono::Utc::now() - chrono::Duration::hours(48);
97+
98+
let mut topics = client
99+
.list_topics()
100+
.set_project(format!("projects/{project_id}"))
101+
.by_item();
102+
103+
let mut pending = Vec::new();
104+
let mut names = Vec::new();
105+
while let Some(topic) = topics.next().await {
106+
let topic = topic?;
107+
if topic
108+
.labels
109+
.get("integration-test")
110+
.is_some_and(|v| v == "true")
111+
&& topic
112+
.labels
113+
.get("create-time")
114+
.and_then(|v| v.parse::<i64>().ok())
115+
.and_then(|s| chrono::DateTime::from_timestamp(s, 0))
116+
.is_some_and(|create_time| create_time < stale_deadline)
117+
{
118+
let client = client.clone();
119+
let name = topic.name.clone();
120+
pending.push(tokio::spawn(async move {
121+
cleanup_test_topic(&client, name).await
122+
}));
123+
names.push(topic.name);
124+
}
125+
}
126+
127+
let r: std::result::Result<Vec<_>, _> = futures::future::join_all(pending)
128+
.await
129+
.into_iter()
130+
.collect();
131+
r.map_err(Error::from)?
132+
.into_iter()
133+
.zip(names)
134+
.for_each(|(r, name)| tracing::info!("deleting topic {name} resulted in {r:?}"));
135+
136+
Ok(())
137+
}

0 commit comments

Comments
 (0)