-
Notifications
You must be signed in to change notification settings - Fork 975
Adding multi-node ZKCluster test util class #1753
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
bookkeeper-server/src/test/java/org/apache/bookkeeper/test/ZooKeeperCluster.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| /* | ||
| * | ||
| * 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.bookkeeper.test; | ||
|
|
||
| import static org.apache.bookkeeper.util.BookKeeperConstants.AVAILABLE_NODE; | ||
| import static org.apache.bookkeeper.util.BookKeeperConstants.READONLY; | ||
|
|
||
| import java.io.IOException; | ||
| import java.util.concurrent.CountDownLatch; | ||
| import java.util.concurrent.TimeUnit; | ||
|
|
||
| import org.apache.bookkeeper.zookeeper.ZooKeeperWatcherBase; | ||
| import org.apache.zookeeper.CreateMode; | ||
| import org.apache.zookeeper.KeeperException; | ||
| import org.apache.zookeeper.Transaction; | ||
| import org.apache.zookeeper.ZooDefs.Ids; | ||
| import org.apache.zookeeper.ZooKeeper; | ||
|
|
||
| /** | ||
| * Interface for ZooKeeperCluster. | ||
| */ | ||
| public interface ZooKeeperCluster { | ||
| ZooKeeper getZooKeeperClient(); | ||
|
|
||
| String getZooKeeperConnectString(); | ||
|
|
||
| String getMetadataServiceUri(); | ||
|
|
||
| String getMetadataServiceUri(String zkLedgersRootPath); | ||
|
|
||
| String getMetadataServiceUri(String zkLedgersRootPath, String type); | ||
|
|
||
| void startCluster() throws Exception; | ||
|
|
||
| void stopCluster() throws Exception; | ||
|
|
||
| void restartCluster() throws Exception; | ||
|
|
||
| void killCluster() throws Exception; | ||
|
|
||
| void sleepCluster(final int time, final TimeUnit timeUnit, final CountDownLatch l) | ||
| throws InterruptedException, IOException; | ||
|
|
||
| default void expireSession(ZooKeeper zk) throws Exception { | ||
| long id = zk.getSessionId(); | ||
| byte[] password = zk.getSessionPasswd(); | ||
| ZooKeeperWatcherBase w = new ZooKeeperWatcherBase(10000); | ||
| ZooKeeper zk2 = new ZooKeeper(getZooKeeperConnectString(), zk.getSessionTimeout(), w, id, password); | ||
| w.waitForConnection(); | ||
| zk2.close(); | ||
| } | ||
|
|
||
| default void createBKEnsemble(String ledgersPath) throws KeeperException, InterruptedException { | ||
| Transaction txn = getZooKeeperClient().transaction(); | ||
| txn.create(ledgersPath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); | ||
| txn.create(ledgersPath + "/" + AVAILABLE_NODE, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); | ||
| txn.create(ledgersPath + "/" + AVAILABLE_NODE + "/" + READONLY, new byte[0], Ids.OPEN_ACL_UNSAFE, | ||
| CreateMode.PERSISTENT); | ||
| txn.commit(); | ||
| } | ||
| } |
140 changes: 140 additions & 0 deletions
140
bookkeeper-server/src/test/java/org/apache/bookkeeper/test/ZooKeeperClusterUtil.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,140 @@ | ||
| /* | ||
| * | ||
| * 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.bookkeeper.test; | ||
|
|
||
| import com.google.common.io.Files; | ||
| import java.io.IOException; | ||
| import java.util.concurrent.CountDownLatch; | ||
| import java.util.concurrent.TimeUnit; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.apache.bookkeeper.meta.LongHierarchicalLedgerManagerFactory; | ||
| import org.apache.bookkeeper.zookeeper.ZooKeeperClient; | ||
| import org.apache.zookeeper.KeeperException; | ||
| import org.apache.zookeeper.ZooKeeper; | ||
| import org.apache.zookeeper.test.QuorumUtil; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| /** | ||
| * Provides multi node zookeeper cluster. | ||
| */ | ||
| @Slf4j | ||
| public class ZooKeeperClusterUtil implements ZooKeeperCluster { | ||
|
|
||
| static { | ||
| enableZookeeperTestEnvVariables(); | ||
| } | ||
|
|
||
| static final Logger LOG = LoggerFactory.getLogger(ZooKeeperClusterUtil.class); | ||
| private final int numOfZKNodes; | ||
| public QuorumUtil quorumUtil; | ||
| String connectString; | ||
| protected ZooKeeper zkc; // zookeeper client | ||
|
|
||
| public static void enableZookeeperTestEnvVariables() { | ||
| /* | ||
| * org.apache.zookeeper.test.ClientBase uses FourLetterWordMain, from | ||
| * 3.5.3 four letter words are disabled by default due to security | ||
| * reasons | ||
| */ | ||
| System.setProperty("zookeeper.4lw.commands.whitelist", "*"); | ||
| System.setProperty("zookeeper.admin.enableServer", "false"); | ||
| try { | ||
| System.setProperty("build.test.dir", Files.createTempDir().getCanonicalPath()); | ||
| } catch (IOException e) { | ||
| log.error("Failed to create temp dir, so setting build.test.dir system property to /tmp"); | ||
| System.setProperty("build.test.dir", "/tmp"); | ||
| } | ||
| } | ||
|
|
||
| public ZooKeeperClusterUtil(int numOfZKNodes) throws IOException, KeeperException, InterruptedException { | ||
| if ((numOfZKNodes < 3) || (numOfZKNodes % 2 == 0)) { | ||
| throw new IllegalArgumentException("numOfZKNodes should be atleast 3 and it should not be even number"); | ||
| } | ||
| this.numOfZKNodes = numOfZKNodes; | ||
| } | ||
|
|
||
| @Override | ||
| public String getZooKeeperConnectString() { | ||
| return connectString; | ||
| } | ||
|
|
||
| @Override | ||
| public String getMetadataServiceUri() { | ||
| return getMetadataServiceUri("/ledgers"); | ||
| } | ||
|
|
||
| @Override | ||
| public String getMetadataServiceUri(String zkLedgersRootPath) { | ||
| return getMetadataServiceUri(zkLedgersRootPath, LongHierarchicalLedgerManagerFactory.NAME); | ||
| } | ||
|
|
||
| @Override | ||
| public String getMetadataServiceUri(String zkLedgersRootPath, String type) { | ||
| /* | ||
| * URI doesn't accept ',', for more info. check | ||
| * AbstractConfiguration.getMetadataServiceUri() | ||
| */ | ||
| return "zk+" + type + "://" + connectString.replace(",", ";") + zkLedgersRootPath; | ||
| } | ||
|
|
||
| @Override | ||
| public ZooKeeper getZooKeeperClient() { | ||
| return zkc; | ||
| } | ||
|
|
||
| @Override | ||
| public void startCluster() throws Exception { | ||
| // QuorumUtil will start 2*n+1 nodes. | ||
| quorumUtil = new QuorumUtil(numOfZKNodes / 2); | ||
| quorumUtil.startAll(); | ||
| connectString = quorumUtil.getConnString(); | ||
| // create a zookeeper client | ||
| LOG.debug("Instantiate ZK Client"); | ||
| zkc = ZooKeeperClient.newBuilder().connectString(getZooKeeperConnectString()).sessionTimeoutMs(10000).build(); | ||
|
|
||
| // create default bk ensemble | ||
| createBKEnsemble("/ledgers"); | ||
| } | ||
|
|
||
| @Override | ||
| public void stopCluster() throws Exception { | ||
| if (zkc != null) { | ||
| zkc.close(); | ||
| } | ||
| quorumUtil.shutdownAll(); | ||
| } | ||
|
|
||
| @Override | ||
| public void restartCluster() throws Exception { | ||
| quorumUtil.startAll(); | ||
| } | ||
|
|
||
| @Override | ||
| public void killCluster() throws Exception { | ||
| quorumUtil.tearDown(); | ||
| } | ||
|
|
||
| @Override | ||
| public void sleepCluster(int time, TimeUnit timeUnit, CountDownLatch l) throws InterruptedException, IOException { | ||
| throw new UnsupportedOperationException("sleepServer operation is not supported for ZooKeeperClusterUtil"); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about adding zookeeper.forceSync=no ?
We do not care about fsync in tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from doc -
"Unsafe Options
The following options can be useful, but be careful when you use them. The risk of each is explained along with the explanation of what the variable does.
forceSync
(Java system property: zookeeper.forceSync)
Requires updates to be synced to media of the transaction log before finishing processing the update. If this option is set to no, ZooKeeper will not require updates to be synced to the media."
maybe worth considering, but this must not be specific to multinode zk cluster. So I'll leave it now for this change. We can revisit if it is needed for both kind of zkclusters (singlenode and multinode).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is only for test cases. You don't really need to fsync in test cases, as processes do not crash.
Waiting/forcing an fsync at every zk write is useless in our tests corpus, isn't it?
I mean, this is not a production zk cluster
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couple of things,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay.
I usually just add the sys prop on the command line.
We can think about changing the command line on CI.
Thank you for your explanations