CheckTest.java
/*
* 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.zookeeper.test;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.File;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.TestableZooKeeper;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.client.ZKClientConfig;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.proto.CheckVersionRequest;
import org.apache.zookeeper.proto.ReplyHeader;
import org.apache.zookeeper.proto.RequestHeader;
import org.apache.zookeeper.server.ZKDatabase;
import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
import org.apache.zookeeper.server.quorum.QuorumPeer;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
public class CheckTest extends ClientBase {
@BeforeEach
public void setUp(TestInfo testInfo) throws Exception {
System.setProperty(ZKClientConfig.ZOOKEEPER_REQUEST_TIMEOUT, "2000");
if (testInfo.getDisplayName().contains("Cluster")) {
return;
}
super.setUp();
}
@AfterEach
public void tearDown(TestInfo testInfo) throws Exception {
System.clearProperty(ZKClientConfig.ZOOKEEPER_REQUEST_TIMEOUT);
if (testInfo.getDisplayName().contains("Cluster")) {
return;
}
super.tearDown();
}
@Override
public void setUp() throws Exception {
}
@Override
public void tearDown() throws Exception {
}
private static void checkVersion(TestableZooKeeper zk, String path, int version) throws Exception {
RequestHeader header = new RequestHeader();
header.setType(ZooDefs.OpCode.check);
CheckVersionRequest request = new CheckVersionRequest(path, version);
ReplyHeader replyHeader = zk.submitRequest(header, request, null, null);
if (replyHeader.getErr() != 0) {
throw KeeperException.create(KeeperException.Code.get(replyHeader.getErr()), path);
}
}
private void testOperations(TestableZooKeeper zk) throws Exception {
Stat stat = new Stat();
zk.getData("/", false, stat);
assertThrows(KeeperException.UnimplementedException.class, () -> checkVersion(zk, "/", -1));
}
@Test
public void testStandalone() throws Exception {
testOperations(createClient());
}
@Test
public void testStandaloneDatabaseReloadAfterCheck() throws Exception {
try {
testOperations(createClient());
} catch (Throwable ignored) {
// Ignore to test database reload after check
}
stopServer();
startServer();
}
@Test
public void testCluster() throws Exception {
QuorumBase qb = new QuorumBase();
try {
qb.setUp(true, true);
testOperations(qb.createClient(new CountdownWatcher(), QuorumPeer.ServerState.OBSERVING));
testOperations(qb.createClient(new CountdownWatcher(), QuorumPeer.ServerState.FOLLOWING));
testOperations(qb.createClient(new CountdownWatcher(), QuorumPeer.ServerState.LEADING));
} finally {
try {
qb.tearDown();
} catch (Exception ignored) {}
}
}
@Test
public void testClusterDatabaseReloadAfterCheck() throws Exception {
QuorumBase qb = new QuorumBase();
try {
qb.setUp(true, true);
// Get leader before possible damaging operations to
// reduce chance of leader migration and log truncation.
File dataDir = qb.getLeaderDataDir();
QuorumPeer leader = qb.getLeaderQuorumPeer();
try {
testOperations(qb.createClient(new CountdownWatcher(), QuorumPeer.ServerState.LEADING));
} catch (Throwable ignored) {
// Ignore to test database reload after check
}
qb.shutdown(leader);
FileTxnSnapLog txnSnapLog = new FileTxnSnapLog(dataDir, dataDir);
ZKDatabase database = new ZKDatabase(txnSnapLog);
database.loadDataBase();
} finally {
try {
qb.tearDown();
} catch (Exception ignored) {}
}
}
}