| /** |
| * 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. |
| */ |
| #include <gtest/gtest.h> |
| #include <lib/TopicName.h> |
| #include <map> |
| |
| using namespace pulsar; |
| |
| TEST(TopicNameTest, testLookup) { |
| std::shared_ptr<TopicName> topicName = TopicName::get("persistent://pulsar/bf1/TESTNS.0/curveballapps"); |
| std::string lookup_name = topicName->getLookupName(); |
| ASSERT_EQ(lookup_name, "persistent/pulsar/bf1/TESTNS.0/curveballapps"); |
| } |
| |
| TEST(TopicNameTest, testTopicName) { |
| // Compare getters and setters |
| std::shared_ptr<TopicName> topicName = TopicName::get("persistent://property/cluster/namespace/topic"); |
| ASSERT_EQ("property", topicName->getProperty()); |
| ASSERT_EQ("cluster", topicName->getCluster()); |
| ASSERT_EQ("namespace", topicName->getNamespacePortion()); |
| ASSERT_EQ("persistent", topicName->getDomain()); |
| ASSERT_EQ(TopicName::getEncodedName("topic"), topicName->getLocalName()); |
| |
| // Compare == operator |
| std::shared_ptr<TopicName> topicName1 = TopicName::get("persistent://p/c/n/d"); |
| std::shared_ptr<TopicName> topicName2 = TopicName::get("persistent://p/c/n/d"); |
| ASSERT_TRUE(*topicName1 == *topicName2); |
| } |
| |
| TEST(TopicNameTest, testShortTopicName) { |
| // "short-topic" |
| std::shared_ptr<TopicName> tn1 = TopicName::get("short-topic"); |
| ASSERT_EQ("public", tn1->getProperty()); |
| ASSERT_EQ("", tn1->getCluster()); |
| ASSERT_EQ("default", tn1->getNamespacePortion()); |
| ASSERT_EQ("persistent", tn1->getDomain()); |
| ASSERT_EQ(TopicName::getEncodedName("short-topic"), tn1->getLocalName()); |
| |
| // tenant/namespace/topic |
| std::shared_ptr<TopicName> tn2 = TopicName::get("tenant/namespace/short-topic"); |
| ASSERT_EQ("tenant", tn2->getProperty()); |
| ASSERT_EQ("", tn2->getCluster()); |
| ASSERT_EQ("namespace", tn2->getNamespacePortion()); |
| ASSERT_EQ("persistent", tn2->getDomain()); |
| ASSERT_EQ(TopicName::getEncodedName("short-topic"), tn2->getLocalName()); |
| |
| // tenant/cluster/namespace/topic |
| std::shared_ptr<TopicName> tn3 = TopicName::get("tenant/cluster/namespace/short-topic"); |
| ASSERT_FALSE(tn3); |
| |
| // tenant/cluster |
| std::shared_ptr<TopicName> tn4 = TopicName::get("tenant/cluster"); |
| ASSERT_FALSE(tn4); |
| } |
| |
| TEST(TopicNameTest, testTopicNameV2) { |
| // v2 topic names doesn't have "cluster" |
| std::shared_ptr<TopicName> tn1 = TopicName::get("persistent://tenant/namespace/short-topic"); |
| ASSERT_EQ("tenant", tn1->getProperty()); |
| ASSERT_EQ("", tn1->getCluster()); |
| ASSERT_EQ("namespace", tn1->getNamespacePortion()); |
| ASSERT_EQ("persistent", tn1->getDomain()); |
| ASSERT_EQ(TopicName::getEncodedName("short-topic"), tn1->getLocalName()); |
| } |
| |
| TEST(TopicNameTest, testNonPersistentTopicNameV2) { |
| // v2 topic names doesn't have "cluster" |
| std::shared_ptr<TopicName> tn1 = TopicName::get("non-persistent://tenant/namespace/short-topic"); |
| ASSERT_EQ("tenant", tn1->getProperty()); |
| ASSERT_EQ("", tn1->getCluster()); |
| ASSERT_EQ("namespace", tn1->getNamespacePortion()); |
| ASSERT_EQ("non-persistent", tn1->getDomain()); |
| ASSERT_EQ(TopicName::getEncodedName("short-topic"), tn1->getLocalName()); |
| } |
| |
| TEST(TopicNameTest, testTopicNameWithSlashes) { |
| // Compare getters and setters |
| std::shared_ptr<TopicName> topicName = |
| TopicName::get("persistent://property/cluster/namespace/topic/name/with/slash"); |
| ASSERT_EQ("property", topicName->getProperty()); |
| ASSERT_EQ("cluster", topicName->getCluster()); |
| ASSERT_EQ("namespace", topicName->getNamespacePortion()); |
| ASSERT_EQ("persistent", topicName->getDomain()); |
| ASSERT_EQ("topic/name/with/slash", topicName->getLocalName()); |
| |
| topicName = TopicName::get("persistent://property/cluster/namespace/topic/ends/with/slash/"); |
| ASSERT_TRUE(topicName != NULL); |
| ASSERT_EQ(TopicName::getEncodedName("topic/ends/with/slash/"), topicName->getEncodedLocalName()); |
| |
| topicName = TopicName::get("persistent://property/cluster/namespace/`~!@#$%^&*()-_+=[]{}|\\;:'\"<>,./?"); |
| ASSERT_TRUE(topicName != NULL); |
| ASSERT_EQ(TopicName::getEncodedName("`~!@#$%^&*()-_+=[]{}|\\;:'\"<>,./?"), |
| topicName->getEncodedLocalName()); |
| |
| topicName = TopicName::get("persistent://property/cluster/namespace/topic@%*)(&!%$#@#$><?"); |
| ASSERT_TRUE(topicName != NULL); |
| ASSERT_EQ(TopicName::getEncodedName("topic@%*)(&!%$#@#$><?"), topicName->getEncodedLocalName()); |
| |
| topicName = TopicName::get("persistent://property/cluster/namespace/topic//with//double//slash//"); |
| ASSERT_TRUE(topicName != NULL); |
| ASSERT_EQ(TopicName::getEncodedName("topic//with//double//slash//"), topicName->getEncodedLocalName()); |
| |
| topicName = TopicName::get("persistent://property/cluster/namespace//topic/starts/with/slash/"); |
| ASSERT_TRUE(topicName != NULL); |
| ASSERT_EQ(TopicName::getEncodedName("/topic/starts/with/slash/"), topicName->getEncodedLocalName()); |
| } |
| TEST(TopicNameTest, testEmptyClusterName) { |
| // Compare getters and setters |
| std::shared_ptr<TopicName> topicName = TopicName::get("persistent://property//namespace/topic"); |
| |
| ASSERT_FALSE(topicName); |
| } |
| |
| TEST(TopicNameTest, testExtraSlashes) { |
| std::shared_ptr<TopicName> topicName = TopicName::get("persistent://property/cluster//namespace/topic"); |
| ASSERT_FALSE(topicName); |
| topicName = TopicName::get("persistent://property//cluster//namespace//topic"); |
| ASSERT_FALSE(topicName); |
| } |
| |
| TEST(TopicNameTest, testIllegalCharacters) { |
| std::shared_ptr<TopicName> topicName = |
| TopicName::get("persistent://prop!!!erty/cluster&)&Name/name%%%space/topic"); |
| ASSERT_FALSE(topicName); |
| } |
| |
| TEST(TopicNameTest, testIllegalUrl) { |
| std::shared_ptr<TopicName> topicName = TopicName::get("persistent:::/property/cluster/namespace/topic"); |
| ASSERT_FALSE(topicName); |
| } |
| |
| TEST(TopicNameTest, testEmptyString) { |
| std::shared_ptr<TopicName> topicName = TopicName::get(""); |
| ASSERT_FALSE(topicName); |
| } |
| |
| TEST(TopicNameTest, testExtraArguments) { |
| std::shared_ptr<TopicName> topicName = |
| TopicName::get("persistent:::/property/cluster/namespace/topic/some/extra/args"); |
| ASSERT_FALSE(topicName); |
| } |
| |
| TEST(TopicNameTest, testPartitionIndex) { |
| // key: topic name, value: partition index |
| const std::map<std::string, int> nameToPartition = { |
| {"persistent://public/default/xxx-partition-0", 0}, |
| {"xxx-partition-0", 0}, |
| {"xxx-partition-4", 4}, |
| {"xxx-partition-13", 13}, |
| {"xxx-partition-x", -1}, |
| // Following cases are not the right behavior, but it's Java client's behavior |
| {"xxx-partition--1", 1}, |
| {"xxx-partition-00", 0}, |
| {"xxx-partition-012", 12}, |
| }; |
| |
| for (const auto& kv : nameToPartition) { |
| const auto& name = kv.first; |
| const auto& partition = kv.second; |
| |
| auto topicName = TopicName::get(name); |
| ASSERT_EQ(topicName->getPartitionIndex(), TopicName::getPartitionIndex(name)); |
| ASSERT_EQ(topicName->getPartitionIndex(), partition); |
| } |
| } |