This is an automated email from the ASF dual-hosted git repository. sijie pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/pulsar.git
The following commit(s) were added to refs/heads/master by this push: new d26bea8 [integration tests] add a smoketest for pulsar standalone (#2732) d26bea8 is described below commit d26bea8f19112ce1581b62ea59a2d8a2cc5a4d85 Author: Sijie Guo <guosi...@gmail.com> AuthorDate: Fri Oct 5 15:26:08 2018 -0700 [integration tests] add a smoketest for pulsar standalone (#2732) *Motivation* Ideally we should run all integration tests on both cluster mode and standalone mode. However the apache ci can't really afford to do so. so we run all the integration tests on cluster mode. We only run basic validation and test new features (e.g. state) on standalone. *Changes* Add PulsarStandalone related test base and suite and a simmple smoke test. This would set the framework for integration tests for state --- .../integration/containers/PulsarContainer.java | 5 +- .../containers/StandaloneContainer.java | 65 +++++++++++++++ .../tests/integration/semantics/SemanticsTest.java | 33 +------- .../tests/integration/standalone/SmokeTest.java | 32 ++++++++ .../suites/PulsarStandaloneTestSuite.java | 43 ++++++++++ .../topologies/PulsarClusterTestBase.java | 35 +------- .../topologies/PulsarStandaloneTestBase.java | 83 +++++++++++++++++++ .../integration/topologies/PulsarTestBase.java | 93 ++++++++++++++++++++++ .../src/test/resources/pulsar-standalone.xml | 28 +++++++ 9 files changed, 352 insertions(+), 65 deletions(-) diff --git a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/PulsarContainer.java b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/PulsarContainer.java index ad77b62..7650d8f 100644 --- a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/PulsarContainer.java +++ b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/PulsarContainer.java @@ -101,6 +101,8 @@ public abstract class PulsarContainer<SelfT extends PulsarContainer<SelfT>> exte } } + protected void beforeStart() {} + @Override public void start() { if (httpPort > 0 && servicePort < 0) { @@ -118,7 +120,8 @@ public abstract class PulsarContainer<SelfT extends PulsarContainer<SelfT>> exte createContainerCmd.withName(getContainerName()); createContainerCmd.withEntrypoint(serviceEntryPoint); }); - + + beforeStart(); super.start(); log.info("Start pulsar service {} at container {}", serviceName, containerName); } diff --git a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/StandaloneContainer.java b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/StandaloneContainer.java new file mode 100644 index 0000000..60a5748 --- /dev/null +++ b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/StandaloneContainer.java @@ -0,0 +1,65 @@ +/** + * 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.pulsar.tests.integration.containers; + +import static java.time.temporal.ChronoUnit.SECONDS; + +import java.time.Duration; +import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; + +/** + * A pulsar container that runs standalone. + */ +public class StandaloneContainer extends PulsarContainer<StandaloneContainer> { + + public static final String NAME = "standalone"; + + public StandaloneContainer(String clusterName) { + super(clusterName, + NAME, + NAME + "-cluster", + "bin/pulsar", + BROKER_PORT, + BROKER_HTTP_PORT); + } + + @Override + protected void configure() { + super.configure(); + setCommand("standalone"); + } + + @Override + protected void beforeStart() { + // update the wait strategy until public/default namespace is created + this.waitStrategy = new HttpWaitStrategy() + .forPort(BROKER_HTTP_PORT) + .forStatusCode(200) + .forPath("/admin/v2/namespaces/public/default") + .withStartupTimeout(Duration.of(300, SECONDS)); + } + + public String getPlainTextServiceUrl() { + return "pulsar://" + getContainerIpAddress() + ":" + getMappedPort(BROKER_PORT); + } + + public String getHttpServiceUrl() { + return "http://" + getContainerIpAddress() + ":" + getMappedPort(BROKER_HTTP_PORT); + } +} diff --git a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/semantics/SemanticsTest.java b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/semantics/SemanticsTest.java index 84dfad1..37f3983 100644 --- a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/semantics/SemanticsTest.java +++ b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/semantics/SemanticsTest.java @@ -41,7 +41,7 @@ import org.apache.pulsar.client.api.SubscriptionInitialPosition; import org.apache.pulsar.client.api.SubscriptionType; import org.apache.pulsar.client.impl.BatchMessageIdImpl; import org.apache.pulsar.client.impl.TopicMessageIdImpl; -import org.apache.pulsar.tests.integration.topologies.PulsarClusterTestBase; +import org.apache.pulsar.tests.integration.suites.PulsarTestSuite; import org.testng.annotations.Test; import org.testng.collections.Lists; @@ -49,7 +49,7 @@ import org.testng.collections.Lists; * Test pulsar produce/consume semantics */ @Slf4j -public class SemanticsTest extends PulsarClusterTestBase { +public class SemanticsTest extends PulsarTestSuite { // // Test Basic Publish & Consume Operations @@ -57,34 +57,7 @@ public class SemanticsTest extends PulsarClusterTestBase { @Test(dataProvider = "ServiceUrlAndTopics") public void testPublishAndConsume(String serviceUrl, boolean isPersistent) throws Exception { - String topicName = generateTopicName("testpubconsume", isPersistent); - - int numMessages = 10; - - try (PulsarClient client = PulsarClient.builder() - .serviceUrl(serviceUrl) - .build()) { - - try (Consumer<String> consumer = client.newConsumer(Schema.STRING) - .topic(topicName) - .subscriptionName("my-sub") - .subscribe()) { - - try (Producer<String> producer = client.newProducer(Schema.STRING) - .topic(topicName) - .create()) { - - for (int i = 0; i < numMessages; i++) { - producer.send("smoke-message-" + i); - } - } - - for (int i = 0; i < numMessages; i++) { - Message<String> m = consumer.receive(); - assertEquals("smoke-message-" + i, m.getValue()); - } - } - } + super.testPublishAndConsume(serviceUrl, isPersistent); } @Test(dataProvider = "ServiceUrls") diff --git a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/standalone/SmokeTest.java b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/standalone/SmokeTest.java new file mode 100644 index 0000000..2b658fa --- /dev/null +++ b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/standalone/SmokeTest.java @@ -0,0 +1,32 @@ +/** + * 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.pulsar.tests.integration.standalone; + +import org.apache.pulsar.tests.integration.suites.PulsarStandaloneTestSuite; +import org.testng.annotations.Test; + + +public class SmokeTest extends PulsarStandaloneTestSuite { + + @Test(dataProvider = "StandaloneServiceUrlAndTopics") + public void testPublishAndConsume(String serviceUrl, boolean isPersistent) throws Exception { + super.testPublishAndConsume(serviceUrl, isPersistent); + } + +} diff --git a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/suites/PulsarStandaloneTestSuite.java b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/suites/PulsarStandaloneTestSuite.java new file mode 100644 index 0000000..15e82e3 --- /dev/null +++ b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/suites/PulsarStandaloneTestSuite.java @@ -0,0 +1,43 @@ +/** + * 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.pulsar.tests.integration.suites; + +import org.apache.pulsar.tests.integration.topologies.PulsarStandaloneTestBase; +import org.testng.ITest; +import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeSuite; + +public class PulsarStandaloneTestSuite extends PulsarStandaloneTestBase implements ITest { + + @BeforeSuite + public void setUpCluster() throws Exception { + super.startCluster(); + } + + @AfterSuite + public void tearDownCluster() throws Exception { + super.stopCluster(); + } + + + @Override + public String getTestName() { + return "pulsar-standalone-suite"; + } +} diff --git a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarClusterTestBase.java b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarClusterTestBase.java index 6181192..883cd6f 100644 --- a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarClusterTestBase.java +++ b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarClusterTestBase.java @@ -21,13 +21,12 @@ package org.apache.pulsar.tests.integration.topologies; import lombok.extern.slf4j.Slf4j; import org.testng.annotations.DataProvider; -import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Stream; import static java.util.stream.Collectors.joining; @Slf4j -public abstract class PulsarClusterTestBase { +public abstract class PulsarClusterTestBase extends PulsarTestBase { @DataProvider(name = "ServiceUrlAndTopics") public static Object[][] serviceUrlAndTopics() { @@ -112,36 +111,4 @@ public abstract class PulsarClusterTestBase { } } - public static String randomName(int numChars) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < numChars; i++) { - sb.append((char) (ThreadLocalRandom.current().nextInt(26) + 'a')); - } - return sb.toString(); - } - - protected static String generateNamespaceName() { - return "ns-" + randomName(8); - } - - protected static String generateTopicName(String topicPrefix, boolean isPersistent) { - return generateTopicName("default", topicPrefix, isPersistent); - } - - protected static String generateTopicName(String namespace, String topicPrefix, boolean isPersistent) { - String topicName = new StringBuilder(topicPrefix) - .append("-") - .append(randomName(8)) - .append("-") - .append(System.currentTimeMillis()) - .toString(); - if (isPersistent) { - return "persistent://public/" + namespace + "/" + topicName; - } else { - return "non-persistent://public/" + namespace + "/" + topicName; - } - } - - - } diff --git a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarStandaloneTestBase.java b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarStandaloneTestBase.java new file mode 100644 index 0000000..48c7fe6 --- /dev/null +++ b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarStandaloneTestBase.java @@ -0,0 +1,83 @@ +/** + * 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.pulsar.tests.integration.topologies; + +import static org.testng.Assert.assertEquals; + +import lombok.extern.slf4j.Slf4j; +import org.apache.pulsar.tests.integration.containers.StandaloneContainer; +import org.apache.pulsar.tests.integration.docker.ContainerExecResult; +import org.testcontainers.containers.Network; +import org.testng.annotations.DataProvider; + +/** + * A test base to run tests on standalone cluster. + * + * <p>Ideally we should run all integration tests on both cluster mode and standalone + * mode. However the apache ci can't really afford to do so. so we run all the integration + * tests on cluster mode. We only run basic validation and test new features (e.g. state) + * on standalone. + */ +@Slf4j +public abstract class PulsarStandaloneTestBase extends PulsarTestBase { + + @DataProvider(name = "StandaloneServiceUrlAndTopics") + public static Object[][] serviceUrlAndTopics() { + return new Object[][] { + // plain text, persistent topic + { + container.getPlainTextServiceUrl(), + true, + }, + // plain text, non-persistent topic + { + container.getPlainTextServiceUrl(), + false + } + }; + } + + protected static Network network; + protected static StandaloneContainer container; + + protected void startCluster() throws Exception { + network = Network.newNetwork(); + String clusterName = PulsarClusterTestBase.randomName(8); + container = new StandaloneContainer(clusterName) + .withNetwork(network) + .withNetworkAliases(StandaloneContainer.NAME + "-" + clusterName); + container.tailContainerLog(); + container.start(); + log.info("Pulsar cluster {} is up running:", clusterName); + log.info("\tBinary Service Url : {}", container.getPlainTextServiceUrl()); + log.info("\tHttp Service Url : {}", container.getHttpServiceUrl()); + + // add cluster to public tenant + ContainerExecResult result = container.execCmd( + "/pulsar/bin/pulsar-admin", "namespaces", "policies", "public/default"); + assertEquals(0, result.getExitCode()); + log.info("public/default namespace policies are {}", result.getStdout()); + } + + protected void stopCluster() throws Exception { + container.stop(); + network.close(); + } + +} diff --git a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarTestBase.java b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarTestBase.java new file mode 100644 index 0000000..2724be2 --- /dev/null +++ b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/topologies/PulsarTestBase.java @@ -0,0 +1,93 @@ +/** + * 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.pulsar.tests.integration.topologies; + +import static org.testng.Assert.assertEquals; + +import java.util.concurrent.ThreadLocalRandom; +import org.apache.pulsar.client.api.Consumer; +import org.apache.pulsar.client.api.Message; +import org.apache.pulsar.client.api.Producer; +import org.apache.pulsar.client.api.PulsarClient; +import org.apache.pulsar.client.api.Schema; + +public class PulsarTestBase { + + public static String randomName(int numChars) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < numChars; i++) { + sb.append((char) (ThreadLocalRandom.current().nextInt(26) + 'a')); + } + return sb.toString(); + } + + protected static String generateNamespaceName() { + return "ns-" + randomName(8); + } + + protected static String generateTopicName(String topicPrefix, boolean isPersistent) { + return generateTopicName("default", topicPrefix, isPersistent); + } + + protected static String generateTopicName(String namespace, String topicPrefix, boolean isPersistent) { + String topicName = new StringBuilder(topicPrefix) + .append("-") + .append(randomName(8)) + .append("-") + .append(System.currentTimeMillis()) + .toString(); + if (isPersistent) { + return "persistent://public/" + namespace + "/" + topicName; + } else { + return "non-persistent://public/" + namespace + "/" + topicName; + } + } + + public void testPublishAndConsume(String serviceUrl, boolean isPersistent) throws Exception { + String topicName = generateTopicName("testpubconsume", isPersistent); + + int numMessages = 10; + + try (PulsarClient client = PulsarClient.builder() + .serviceUrl(serviceUrl) + .build()) { + + try (Consumer<String> consumer = client.newConsumer(Schema.STRING) + .topic(topicName) + .subscriptionName("my-sub") + .subscribe()) { + + try (Producer<String> producer = client.newProducer(Schema.STRING) + .topic(topicName) + .create()) { + + for (int i = 0; i < numMessages; i++) { + producer.send("smoke-message-" + i); + } + } + + for (int i = 0; i < numMessages; i++) { + Message<String> m = consumer.receive(); + assertEquals("smoke-message-" + i, m.getValue()); + } + } + } + } + +} diff --git a/tests/integration/src/test/resources/pulsar-standalone.xml b/tests/integration/src/test/resources/pulsar-standalone.xml new file mode 100644 index 0000000..8a5a823 --- /dev/null +++ b/tests/integration/src/test/resources/pulsar-standalone.xml @@ -0,0 +1,28 @@ +<!-- + + 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. + +--> +<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > +<suite name="Pulsar Standalone Tests" verbose="2" annotations="JDK"> + <test name="pulsar-standalone-suite" preserve-order="true" > + <classes> + <class name="org.apache.pulsar.tests.integration.standalone.SmokeTest" /> + </classes> + </test> +</suite> \ No newline at end of file