/** * Licensed to the zk1931 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 com.github.zk1931.jzab; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Test PersistentState. */ public class PersistentStateTest extends TestBase { private static final Logger LOG = LoggerFactory.getLogger(LogTest.class); Class<Log> logClass; @Test public void testEmpty() throws IOException { // Test for empty directory. PersistentState persistence = new PersistentState(getDirectory()); Assert.assertEquals(true, persistence.isEmpty()); Assert.assertEquals(Zxid.ZXID_NOT_EXIST, persistence.getLog().getLatestZxid()); Assert.assertEquals(-1, persistence.getProposedEpoch()); Assert.assertEquals(-1, persistence.getAckEpoch()); Assert.assertEquals(null, persistence.getLastSeenConfig()); } @Test public void testReadWrite() throws IOException { // Test Read/Write log. PersistentState persistence = new PersistentState(getDirectory()); persistence.setProposedEpoch(2); persistence.setAckEpoch(3); Transaction txn = new Transaction(new Zxid(0, 0), ByteBuffer.wrap("txn".getBytes())); persistence.getLog().append(txn); ClusterConfiguration cnf = new ClusterConfiguration(new Zxid(0, 1), new ArrayList<String>(), "v"); persistence.setLastSeenConfig(cnf); Assert.assertEquals(2, persistence.getProposedEpoch()); Assert.assertEquals(3, persistence.getAckEpoch()); Assert.assertEquals(new Zxid(0, 0), persistence.getLog().getLatestZxid()); cnf = persistence.getLastSeenConfig(); Assert.assertEquals(new Zxid(0, 1), cnf.getVersion()); Assert.assertEquals("v", cnf.getServerId()); Assert.assertEquals(true, cnf.getPeers().isEmpty()); } @Test public void testRestore() throws IOException { // Test restore from a log. PersistentState persistence = new PersistentState(getDirectory()); persistence.setProposedEpoch(2); persistence.setAckEpoch(3); Transaction txn = new Transaction(new Zxid(0, 0), ByteBuffer.wrap("txn".getBytes())); persistence.getLog().append(txn); ClusterConfiguration cnf = new ClusterConfiguration(new Zxid(0, 1), new ArrayList<String>(), "v"); persistence.setLastSeenConfig(cnf); // Recovers. persistence = new PersistentState(getDirectory()); Assert.assertEquals(2, persistence.getProposedEpoch()); Assert.assertEquals(3, persistence.getAckEpoch()); Assert.assertEquals(new Zxid(0, 0), persistence.getLog().getLatestZxid()); cnf = persistence.getLastSeenConfig(); Assert.assertEquals(new Zxid(0, 1), cnf.getVersion()); Assert.assertEquals("v", cnf.getServerId()); Assert.assertEquals(true, cnf.getPeers().isEmpty()); } @Test public void testStateTransfering() throws IOException { PersistentState persistence = new PersistentState(getDirectory()); appendTxns(persistence.getLog(), new Zxid(0, 0), 2); Assert.assertEquals(new Zxid(0, 1), persistence.getLatestZxid()); /* * Test case 1: * * Appends 100 txns in state transferring mode then ends transferring mode * and verify they show up in log. */ // Begins state transferring mode. persistence.beginStateTransfer(); // Make sure it's in state transferring mode. Assert.assertTrue(persistence.isInStateTransfer()); // Appends 100 txns. appendTxns(persistence.getLog(), new Zxid(0, 0), 100); // Make sure the appended txns show up. Assert.assertEquals(new Zxid(0, 99), persistence.getLatestZxid()); // Ends state transferring. persistence.endStateTransfer(); // Restores state. persistence = new PersistentState(getDirectory()); // Make sure the appended txns show up. Assert.assertEquals(new Zxid(0, 99), persistence.getLatestZxid()); /* * Test case 2: * * Appends 10 txns in state transferring mode, but without calling * endStateTransfering we restore persistent state and verify the * 10 txns will not show up. */ // Begins state transferring mode again. persistence.beginStateTransfer(); // Make sure it's in state transferring mode. Assert.assertTrue(persistence.isInStateTransfer()); // Appends 10 txns. appendTxns(persistence.getLog(), new Zxid(0, 0), 10); // Make sure the appended txns show up. Assert.assertEquals(new Zxid(0, 9), persistence.getLatestZxid()); // But we'll not call endStateTransfering, the intermediate result will be // discarded. persistence = new PersistentState(getDirectory()); // Still show old data. Assert.assertEquals(new Zxid(0, 99), persistence.getLatestZxid()); /* * Test case 3: * * Appends 10 txns in state transferring mode, but without calling * endStateTransfering we undo the state transferring explicitly and verify * the 10 txns will not show up. */ persistence.beginStateTransfer(); // Appends 10 txns. appendTxns(persistence.getLog(), new Zxid(0, 0), 10); // Make sure the appended txns show up. Assert.assertEquals(new Zxid(0, 9), persistence.getLatestZxid()); Assert.assertTrue(persistence.isInStateTransfer()); // Undo state transferring manually. persistence.undoStateTransfer(); // Still show old data. Assert.assertEquals(new Zxid(0, 99), persistence.getLatestZxid()); } @Test public void testClusterConfigFiles() throws IOException { Set<String> peers = new HashSet<String>(); ClusterConfiguration cnf = new ClusterConfiguration(new Zxid(0, -1), peers, ""); PersistentState persistence = new PersistentState(getDirectory()); persistence.setLastSeenConfig(cnf); cnf = new ClusterConfiguration(new Zxid(0, 1), peers, ""); persistence.setLastSeenConfig(cnf); // Make sures <0, -1> is smaller than <0, 1>. Assert.assertEquals(persistence.getLastSeenConfig().getVersion(), new Zxid(0, 1)); } @Test public void testCleanupClusterConfigFiles() throws IOException { PersistentState persistence = new PersistentState(getDirectory()); Set<String> peers = new HashSet<String>(); ClusterConfiguration cnf = new ClusterConfiguration(new Zxid(0, -1), peers, ""); // Initialy set version to <0, -1> persistence.setLastSeenConfig(cnf); // Appends 3 txns so the latest zxid is <0, 2> appendTxns(persistence.getLog(), new Zxid(0, 0), 3); // Sets config files with version <0, 3> ~ <0, 5> for (int i = 3; i < 6; ++i) { cnf = new ClusterConfiguration(new Zxid(0, i), peers, ""); persistence.setLastSeenConfig(cnf); } Assert.assertEquals(persistence.getLastSeenConfig().getVersion(), new Zxid(0, 5)); // Latest zxid in log is <0, 2>, the latest zxid of config is // <0, 3>, this one will be deleted. persistence.cleanupClusterConfigFiles(); Assert.assertEquals(persistence.getLastSeenConfig().getVersion(), new Zxid(0, -1)); cnf = new ClusterConfiguration(new Zxid(0, 2), peers, ""); persistence.setLastSeenConfig(cnf); persistence.cleanupClusterConfigFiles(); // After cleaning up, the version of config should be <0, 2>. Assert.assertEquals(persistence.getLastSeenConfig().getVersion(), new Zxid(0, 2)); } @Test public void testLastConfig() throws IOException { PersistentState persistence = new PersistentState(getDirectory()); Set<String> peers = new HashSet<String>(); ClusterConfiguration cnf = new ClusterConfiguration(new Zxid(0, 1), peers, ""); // Initialy set version to <0, 1> persistence.setLastSeenConfig(cnf); cnf = persistence.getLastConfigWithin(new Zxid(0, 1)); // Now the last config within <0, 1> should be <0, 1> Assert.assertEquals(new Zxid(0, 1), cnf.getVersion()); cnf = new ClusterConfiguration(new Zxid(0, 2), peers, ""); persistence.setLastSeenConfig(cnf); // Now the last config within <0, 2> should be <0, 2> cnf = persistence.getLastConfigWithin(new Zxid(0, 2)); Assert.assertEquals(new Zxid(0, 2), cnf.getVersion()); cnf = persistence.getLastConfigWithin(new Zxid(0, 1)); // Now the last config within <0, 1> should be <0, 1> Assert.assertEquals(new Zxid(0, 1), cnf.getVersion()); cnf = persistence.getLastConfigWithin(new Zxid(0, 0)); Assert.assertTrue(cnf == null); } }