kevinrr888 commented on code in PR #6040:
URL: https://github.com/apache/accumulo/pull/6040#discussion_r2728680197


##########
test/src/main/java/org/apache/accumulo/test/functional/IteratorConflictsIT.java:
##########
@@ -0,0 +1,816 @@
+/*
+ * 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.functional;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Consumer;
+
+import org.apache.accumulo.core.client.Accumulo;
+import org.apache.accumulo.core.client.AccumuloClient;
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.client.admin.CloneConfiguration;
+import org.apache.accumulo.core.client.admin.NamespaceOperations;
+import org.apache.accumulo.core.client.admin.NewTableConfiguration;
+import org.apache.accumulo.core.client.admin.TableOperations;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.iterators.IteratorUtil;
+import org.apache.accumulo.core.iteratorsImpl.IteratorConfigUtil;
+import org.apache.accumulo.harness.SharedMiniClusterBase;
+import org.apache.hadoop.fs.Path;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.AbstractAppender;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+
+/**
+ * Tests that iterator conflicts are detected and cause exceptions. Iterators 
can be added multiple
+ * ways. This test ensures that:
+ * <p>
+ * - {@link Scanner#addScanIterator(IteratorSetting)}
+ * <p>
+ * - {@link TableOperations#setProperty(String, String, String)}
+ * <p>
+ * - {@link TableOperations#modifyProperties(String, Consumer)}
+ * <p>
+ * - {@link NewTableConfiguration#attachIterator(IteratorSetting, EnumSet)}
+ * <p>
+ * - {@link TableOperations#attachIterator(String, IteratorSetting, EnumSet)}
+ * <p>
+ * - {@link NamespaceOperations#attachIterator(String, IteratorSetting, 
EnumSet)}
+ * <p>
+ * - {@link NamespaceOperations#setProperty(String, String, String)}
+ * <p>
+ * - {@link NamespaceOperations#modifyProperties(String, Consumer)}
+ * <p>
+ * - {@link CloneConfiguration.Builder#setPropertiesToSet(Map)}
+ * <p>
+ * All fail when conflicts arise from:
+ * <p>
+ * - Iterators attached directly to a table
+ * <p>
+ * - Iterators attached to a namespace, inherited by a table
+ * <p>
+ * - Default table iterators, but should not fail if {@link 
NewTableConfiguration#withoutDefaults()}
+ * is specified
+ * <p>
+ * - Adding the exact iterator already present should not fail
+ */
+public class IteratorConflictsIT extends SharedMiniClusterBase {
+  private static TableOperations tops;
+  private static NamespaceOperations nops;
+  private static AccumuloClient client;
+  // doesn't matter what iterator is used here
+  private static final String iterClass = SlowIterator.class.getName();
+  private static final IteratorSetting iter1 = new IteratorSetting(99, 
"iter1name", iterClass);
+  private static final String iter1Key = Property.TABLE_ITERATOR_PREFIX
+      + IteratorUtil.IteratorScope.scan.name().toLowerCase() + "." + 
iter1.getName();
+  private static final String iter1Val = "99," + iterClass;
+  private static final IteratorSetting iter1PrioConflict =
+      new IteratorSetting(99, "othername", iterClass);
+  private static final IteratorSetting iter1NameConflict =
+      new IteratorSetting(101, iter1.getName(), iterClass);
+  private static final String iter1PrioConflictKey = 
Property.TABLE_ITERATOR_PREFIX
+      + IteratorUtil.IteratorScope.scan.name().toLowerCase() + ".othername";
+  private static final String iter1PrioConflictVal = "99," + iterClass;
+  private static final String iter1NameConflictKey = 
Property.TABLE_ITERATOR_PREFIX
+      + IteratorUtil.IteratorScope.scan.name().toLowerCase() + "." + 
iter1.getName();
+  private static final String iter1NameConflictVal = "101," + iterClass;
+  private static final IteratorSetting defaultIterPrioConflict =
+      new IteratorSetting(20, "bar", iterClass);
+  private static final IteratorSetting defaultIterNameConflict =
+      new IteratorSetting(101, "vers", iterClass);
+  private static final IteratorSetting defaultTableIter =
+      
IteratorConfigUtil.getInitialTableIteratorSettings().keySet().iterator().next();
+  private static final String defaultIterPrioConflictKey = 
Property.TABLE_ITERATOR_PREFIX
+      + IteratorUtil.IteratorScope.scan.name().toLowerCase() + ".foo";
+  private static final String defaultIterPrioConflictVal =
+      defaultTableIter.getPriority() + "," + iterClass;
+  private static final String defaultIterNameConflictKey = 
Property.TABLE_ITERATOR_PREFIX
+      + IteratorUtil.IteratorScope.scan.name().toLowerCase() + "." + 
defaultTableIter.getName();
+  private static final String defaultIterNameConflictVal = "99," + iterClass;
+  private static final String defaultIterKey = 
Property.TABLE_ITERATOR_PREFIX.getKey()
+      + IteratorUtil.IteratorScope.scan.name().toLowerCase() + "." + 
defaultTableIter.getName();
+  private static final String defaultIterVal =
+      defaultTableIter.getPriority() + "," + 
defaultTableIter.getIteratorClass();
+  private static final String defaultIterOptKey = 
Property.TABLE_ITERATOR_PREFIX.getKey()
+      + IteratorUtil.IteratorScope.scan.name().toLowerCase() + "." + 
defaultTableIter.getName()
+      + ".opt." + 
defaultTableIter.getOptions().entrySet().iterator().next().getKey();
+  private static final String defaultIterOptVal =
+      defaultTableIter.getOptions().entrySet().iterator().next().getValue();
+
+  private static final LoggerContext loggerContext = (LoggerContext) 
LogManager.getContext(false);
+  private static final Configuration loggerConfig = 
loggerContext.getConfiguration();
+  private static final TestAppender appender = new TestAppender();
+  private static final String datePattern = getDatePattern();
+  private static final DateTimeFormatter dateTimeFormatter =
+      DateTimeFormatter.ofPattern(datePattern);
+
+  public static class TestAppender extends AbstractAppender {
+    // CopyOnWriteArrayList for thread safety, even while iterating
+    private final List<LogEvent> events = new CopyOnWriteArrayList<>();
+
+    public TestAppender() {
+      super("TestAppender", null, PatternLayout.createDefaultLayout(), false, 
null);
+    }
+
+    @Override
+    public void append(LogEvent event) {
+      events.add(event.toImmutable());
+    }
+
+    public List<LogEvent> events() {
+      return events;
+    }
+  }
+
+  @BeforeAll
+  public static void startup() throws Exception {
+    SharedMiniClusterBase.startMiniCluster();
+    client = Accumulo.newClient().from(getClientProps()).build();
+    tops = client.tableOperations();
+    nops = client.namespaceOperations();
+    appender.start();
+    loggerConfig.getRootLogger().addAppender(appender, Level.WARN, null);
+    loggerContext.updateLoggers();
+  }
+
+  @AfterAll
+  public static void shutdown() throws Exception {
+    client.close();
+    SharedMiniClusterBase.stopMiniCluster();
+    loggerConfig.getRootLogger().removeAppender(appender.getName());
+    appender.stop();
+    loggerContext.updateLoggers();

Review Comment:
   addressed in 3244196cc94562658760003627c1b5768067b623



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to