/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ package org.apache.beam.sdk.io.gcp.pubsub; import static org.apache.beam.sdk.transforms.display.DisplayDataMatchers.hasDisplayItem; import static org.hamcrest.Matchers.hasItem; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import java.util.Set; import org.apache.beam.sdk.options.ValueProvider.StaticValueProvider; import org.apache.beam.sdk.testing.UsesUnboundedPCollections; import org.apache.beam.sdk.testing.ValidatesRunner; import org.apache.beam.sdk.transforms.display.DisplayData; import org.apache.beam.sdk.transforms.display.DisplayDataEvaluator; import org.joda.time.Duration; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** * Tests for PubsubIO Read and Write transforms. */ @RunWith(JUnit4.class) public class PubsubIOTest { @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void testPubsubIOGetName() { assertEquals("PubsubIO.Read", PubsubIO.readStrings().fromTopic("projects/myproject/topics/mytopic").getName()); assertEquals("PubsubIO.Write", PubsubIO.writeStrings().to("projects/myproject/topics/mytopic").getName()); } @Test public void testTopicValidationSuccess() throws Exception { PubsubIO.readStrings().fromTopic("projects/my-project/topics/abc"); PubsubIO.readStrings().fromTopic("projects/my-project/topics/ABC"); PubsubIO.readStrings().fromTopic("projects/my-project/topics/AbC-DeF"); PubsubIO.readStrings().fromTopic("projects/my-project/topics/AbC-1234"); PubsubIO.readStrings().fromTopic("projects/my-project/topics/AbC-1234-_.~%+-_.~%+-_.~%+-abc"); PubsubIO.readStrings().fromTopic(new StringBuilder() .append("projects/my-project/topics/A-really-long-one-") .append("111111111111111111111111111111111111111111111111111111111111111111111111111111111") .append("111111111111111111111111111111111111111111111111111111111111111111111111111111111") .append("11111111111111111111111111111111111111111111111111111111111111111111111111") .toString()); } @Test public void testTopicValidationBadCharacter() throws Exception { thrown.expect(IllegalArgumentException.class); PubsubIO.readStrings().fromTopic("projects/my-project/topics/abc-*-abc"); } @Test public void testTopicValidationTooLong() throws Exception { thrown.expect(IllegalArgumentException.class); PubsubIO.readStrings().fromTopic(new StringBuilder().append ("projects/my-project/topics/A-really-long-one-") .append("111111111111111111111111111111111111111111111111111111111111111111111111111111111") .append("111111111111111111111111111111111111111111111111111111111111111111111111111111111") .append("1111111111111111111111111111111111111111111111111111111111111111111111111111") .toString()); } @Test public void testReadTopicDisplayData() { String topic = "projects/project/topics/topic"; String subscription = "projects/project/subscriptions/subscription"; Duration maxReadTime = Duration.standardMinutes(5); PubsubIO.Read<String> read = PubsubIO.readStrings() .fromTopic(StaticValueProvider.of(topic)) .withTimestampAttribute("myTimestamp") .withIdAttribute("myId"); DisplayData displayData = DisplayData.from(read); assertThat(displayData, hasDisplayItem("topic", topic)); assertThat(displayData, hasDisplayItem("timestampAttribute", "myTimestamp")); assertThat(displayData, hasDisplayItem("idAttribute", "myId")); } @Test public void testReadSubscriptionDisplayData() { String topic = "projects/project/topics/topic"; String subscription = "projects/project/subscriptions/subscription"; Duration maxReadTime = Duration.standardMinutes(5); PubsubIO.Read<String> read = PubsubIO.readStrings() .fromSubscription(StaticValueProvider.of(subscription)) .withTimestampAttribute("myTimestamp") .withIdAttribute("myId"); DisplayData displayData = DisplayData.from(read); assertThat(displayData, hasDisplayItem("subscription", subscription)); assertThat(displayData, hasDisplayItem("timestampAttribute", "myTimestamp")); assertThat(displayData, hasDisplayItem("idAttribute", "myId")); } @Test public void testNullTopic() { String subscription = "projects/project/subscriptions/subscription"; PubsubIO.Read<String> read = PubsubIO.readStrings() .fromSubscription(StaticValueProvider.of(subscription)); assertNull(read.getTopicProvider()); assertNotNull(read.getSubscriptionProvider()); assertNotNull(DisplayData.from(read)); } @Test public void testNullSubscription() { String topic = "projects/project/topics/topic"; PubsubIO.Read<String> read = PubsubIO.readStrings() .fromTopic(StaticValueProvider.of(topic)); assertNotNull(read.getTopicProvider()); assertNull(read.getSubscriptionProvider()); assertNotNull(DisplayData.from(read)); } @Test @Category({ValidatesRunner.class, UsesUnboundedPCollections.class}) public void testPrimitiveReadDisplayData() { DisplayDataEvaluator evaluator = DisplayDataEvaluator.create(); Set<DisplayData> displayData; PubsubIO.Read<String> baseRead = PubsubIO.readStrings(); // Reading from a subscription. PubsubIO.Read<String> read = baseRead.fromSubscription("projects/project/subscriptions/subscription"); displayData = evaluator.displayDataForPrimitiveSourceTransforms(read); assertThat( "PubsubIO.Read should include the subscription in its primitive display data", displayData, hasItem(hasDisplayItem("subscription"))); // Reading from a topic. read = baseRead.fromTopic("projects/project/topics/topic"); displayData = evaluator.displayDataForPrimitiveSourceTransforms(read); assertThat("PubsubIO.Read should include the topic in its primitive display data", displayData, hasItem(hasDisplayItem("topic"))); } @Test public void testWriteDisplayData() { String topic = "projects/project/topics/topic"; PubsubIO.Write<?> write = PubsubIO.writeStrings() .to(topic) .withTimestampAttribute("myTimestamp") .withIdAttribute("myId"); DisplayData displayData = DisplayData.from(write); assertThat(displayData, hasDisplayItem("topic", topic)); assertThat(displayData, hasDisplayItem("timestampAttribute", "myTimestamp")); assertThat(displayData, hasDisplayItem("idAttribute", "myId")); } @Test @Category(ValidatesRunner.class) public void testPrimitiveWriteDisplayData() { DisplayDataEvaluator evaluator = DisplayDataEvaluator.create(); PubsubIO.Write<?> write = PubsubIO.writeStrings().to("projects/project/topics/topic"); Set<DisplayData> displayData = evaluator.displayDataForPrimitiveTransforms(write); assertThat("PubsubIO.Write should include the topic in its primitive display data", displayData, hasItem(hasDisplayItem("topic"))); } }