This is an automated email from the ASF dual-hosted git repository. dlmarion pushed a commit to branch 2.1 in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/2.1 by this push: new bc8df24ff8 Created UpgradeUtilIT, fixed issues in UpgradeUtil (#5454) bc8df24ff8 is described below commit bc8df24ff88b9ba05775f584502b6b35150dd995 Author: Dave Marion <dlmar...@apache.org> AuthorDate: Fri Apr 4 17:13:19 2025 -0400 Created UpgradeUtilIT, fixed issues in UpgradeUtil (#5454) --- .../apache/accumulo/server/util/UpgradeUtil.java | 6 +- .../accumulo/test/upgrade/UpgradeUtilIT.java | 102 +++++++++++++++++++++ 2 files changed, 105 insertions(+), 3 deletions(-) diff --git a/server/base/src/main/java/org/apache/accumulo/server/util/UpgradeUtil.java b/server/base/src/main/java/org/apache/accumulo/server/util/UpgradeUtil.java index 5c880da99d..db97283b30 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/util/UpgradeUtil.java +++ b/server/base/src/main/java/org/apache/accumulo/server/util/UpgradeUtil.java @@ -19,7 +19,7 @@ package org.apache.accumulo.server.util; import org.apache.accumulo.core.Constants; -import org.apache.accumulo.core.cli.Help; +import org.apache.accumulo.core.cli.ConfigOpts; import org.apache.accumulo.core.conf.Property; import org.apache.accumulo.core.conf.SiteConfiguration; import org.apache.accumulo.core.data.InstanceId; @@ -46,7 +46,7 @@ public class UpgradeUtil implements KeywordExecutable { private static final Logger LOG = LoggerFactory.getLogger(UpgradeUtil.class); - static class Opts extends Help { + static class Opts extends ConfigOpts { @Parameter(names = "--prepare", description = "prepare an older version instance for an upgrade to a newer non-bugfix release." + " This command should be run using the older version of software after the instance is shut down.") @@ -110,7 +110,7 @@ public class UpgradeUtil implements KeywordExecutable { LOG.info("Checking for existing fate transactions"); try { // Adapted from UpgradeCoordinator.abortIfFateTransactions - if (!zoo.getChildren(Constants.ZFATE).isEmpty()) { + if (!zoo.getChildren(Constants.ZROOT + "/" + iid + Constants.ZFATE).isEmpty()) { throw new IllegalStateException("Cannot complete upgrade preparation" + " because FATE transactions exist. You can start a tserver, but" + " not the Manager, then use the shell to delete completed" diff --git a/test/src/main/java/org/apache/accumulo/test/upgrade/UpgradeUtilIT.java b/test/src/main/java/org/apache/accumulo/test/upgrade/UpgradeUtilIT.java new file mode 100644 index 0000000000..89671ff24f --- /dev/null +++ b/test/src/main/java/org/apache/accumulo/test/upgrade/UpgradeUtilIT.java @@ -0,0 +1,102 @@ +/* + * 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 + * + * https://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.accumulo.test.upgrade; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.UUID; + +import org.apache.accumulo.core.Constants; +import org.apache.accumulo.core.fate.zookeeper.ZooUtil.NodeExistsPolicy; +import org.apache.accumulo.harness.AccumuloClusterHarness; +import org.apache.accumulo.minicluster.ServerType; +import org.apache.accumulo.server.ServerContext; +import org.apache.accumulo.server.util.UpgradeUtil; +import org.apache.accumulo.test.util.Wait; +import org.junit.jupiter.api.Test; + +public class UpgradeUtilIT extends AccumuloClusterHarness { + + @Test + public void testPrepareFailsDueToManagerUp() throws Exception { + ServerContext ctx = getCluster().getServerContext(); + + ctx.getZooReaderWriter().putPersistentData( + ctx.getZooKeeperRoot() + Constants.ZPREPARE_FOR_UPGRADE, new byte[0], + NodeExistsPolicy.SKIP); + assertTrue(ctx.getZooReader().exists(ctx.getZooKeeperRoot() + Constants.ZPREPARE_FOR_UPGRADE)); + + System.setProperty("accumulo.properties", "file://" + getCluster().getAccumuloPropertiesPath()); + IllegalStateException ise = assertThrows(IllegalStateException.class, + () -> new UpgradeUtil().execute(new String[] {"--prepare"})); + assertEquals("Manager is running, shut it down and retry this operation", ise.getMessage()); + assertFalse(ctx.getZooReader().exists(ctx.getZooKeeperRoot() + Constants.ZPREPARE_FOR_UPGRADE)); + + } + + @Test + public void testPrepareFailsDueToFateTransactions() throws Exception { + ServerContext ctx = getCluster().getServerContext(); + + ctx.getZooReaderWriter().putPersistentData( + ctx.getZooKeeperRoot() + Constants.ZPREPARE_FOR_UPGRADE, new byte[0], + NodeExistsPolicy.SKIP); + assertTrue(ctx.getZooReader().exists(ctx.getZooKeeperRoot() + Constants.ZPREPARE_FOR_UPGRADE)); + + assertTrue(ctx.getZooReader().getChildren(ctx.getZooKeeperRoot() + Constants.ZFATE).isEmpty()); + ctx.getZooReaderWriter().putEphemeralData( + ctx.getZooKeeperRoot() + Constants.ZFATE + "/" + UUID.randomUUID(), new byte[0]); + assertFalse(ctx.getZooReader().getChildren(ctx.getZooKeeperRoot() + Constants.ZFATE).isEmpty()); + + getCluster().getClusterControl().stopAllServers(ServerType.MANAGER); + Wait.waitFor(() -> ctx.getZooReader() + .getChildren(ctx.getZooKeeperRoot() + Constants.ZMANAGER_LOCK).isEmpty()); + + System.setProperty("accumulo.properties", "file://" + getCluster().getAccumuloPropertiesPath()); + IllegalStateException ise = assertThrows(IllegalStateException.class, + () -> new UpgradeUtil().execute(new String[] {"--prepare"})); + assertTrue(ise.getMessage() + .startsWith("Cannot complete upgrade preparation because FATE transactions exist.")); + assertFalse(ctx.getZooReader().exists(ctx.getZooKeeperRoot() + Constants.ZPREPARE_FOR_UPGRADE)); + + } + + @Test + public void testPrepareSucceeds() throws Exception { + ServerContext ctx = getCluster().getServerContext(); + + ctx.getZooReaderWriter().putPersistentData( + ctx.getZooKeeperRoot() + Constants.ZPREPARE_FOR_UPGRADE, new byte[0], + NodeExistsPolicy.SKIP); + assertTrue(ctx.getZooReader().exists(ctx.getZooKeeperRoot() + Constants.ZPREPARE_FOR_UPGRADE)); + + getCluster().getClusterControl().stopAllServers(ServerType.MANAGER); + Wait.waitFor(() -> ctx.getZooReader() + .getChildren(ctx.getZooKeeperRoot() + Constants.ZMANAGER_LOCK).isEmpty()); + + System.setProperty("accumulo.properties", "file://" + getCluster().getAccumuloPropertiesPath()); + new UpgradeUtil().execute(new String[] {"--prepare"}); + assertTrue(ctx.getZooReader().exists(ctx.getZooKeeperRoot() + Constants.ZPREPARE_FOR_UPGRADE)); + + } + +}