This is an automated email from the ASF dual-hosted git repository.

domgarguilo 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 c899d61206 Add tests for AccumuloConfiguration.isPropertySet 
implementations (#3676)
c899d61206 is described below

commit c899d612064f7452c47bbc8a414764bee5378a08
Author: Dom G <domgargu...@apache.org>
AuthorDate: Tue Sep 12 12:57:17 2023 -0400

    Add tests for AccumuloConfiguration.isPropertySet implementations (#3676)
    
    Co-authored-by: Christopher Tubbs <ctubb...@apache.org>
---
 .../accumulo/core/conf/AccumuloConfiguration.java  |   4 +
 .../AccumuloConfigurationIsPropertySetTest.java    | 302 +++++++++++++++++++++
 2 files changed, 306 insertions(+)

diff --git 
a/core/src/main/java/org/apache/accumulo/core/conf/AccumuloConfiguration.java 
b/core/src/main/java/org/apache/accumulo/core/conf/AccumuloConfiguration.java
index 3a4bc0f044..636b18db68 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/conf/AccumuloConfiguration.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/conf/AccumuloConfiguration.java
@@ -430,6 +430,10 @@ public abstract class AccumuloConfiguration implements 
Iterable<Entry<String,Str
     }
   }
 
+  /**
+   * @param prop Property to check
+   * @return true if the given property has explicitly been set by a user, 
false otherwise
+   */
   public abstract boolean isPropertySet(Property prop);
 
   // deprecation property warning could get spammy in tserver so only warn once
diff --git 
a/server/base/src/test/java/org/apache/accumulo/server/conf/AccumuloConfigurationIsPropertySetTest.java
 
b/server/base/src/test/java/org/apache/accumulo/server/conf/AccumuloConfigurationIsPropertySetTest.java
new file mode 100644
index 0000000000..4b7ae59a03
--- /dev/null
+++ 
b/server/base/src/test/java/org/apache/accumulo/server/conf/AccumuloConfigurationIsPropertySetTest.java
@@ -0,0 +1,302 @@
+/*
+ * 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.server.conf;
+
+import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
+import static org.apache.accumulo.core.conf.Property.GC_PORT;
+import static org.apache.accumulo.core.conf.Property.INSTANCE_SECRET;
+import static org.apache.accumulo.core.conf.Property.INSTANCE_ZK_HOST;
+import static 
org.apache.accumulo.core.conf.Property.MANAGER_BULK_TSERVER_REGEX;
+import static org.apache.accumulo.core.conf.Property.TABLE_BLOOM_ENABLED;
+import static org.apache.accumulo.core.conf.Property.TABLE_BLOOM_SIZE;
+import static org.apache.accumulo.core.conf.Property.TABLE_DURABILITY;
+import static org.apache.accumulo.core.conf.Property.TABLE_FILE_MAX;
+import static org.apache.accumulo.core.conf.Property.TSERV_SCAN_MAX_OPENFILES;
+import static 
org.apache.accumulo.server.MockServerContext.getMockContextWithPropStore;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.function.Predicate;
+
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.ConfigurationCopy;
+import org.apache.accumulo.core.conf.DefaultConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.conf.SiteConfiguration;
+import org.apache.accumulo.core.data.InstanceId;
+import org.apache.accumulo.core.data.NamespaceId;
+import org.apache.accumulo.core.data.TableId;
+import org.apache.accumulo.server.ServerContext;
+import org.apache.accumulo.server.WithTestNames;
+import org.apache.accumulo.server.conf.codec.VersionedProperties;
+import org.apache.accumulo.server.conf.store.NamespacePropKey;
+import org.apache.accumulo.server.conf.store.SystemPropKey;
+import org.apache.accumulo.server.conf.store.TablePropKey;
+import org.apache.accumulo.server.conf.store.impl.ZooPropStore;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Sets;
+
+/**
+ * Ensure that each implementation of AccumuloConfiguration has a working 
implementation of
+ * isPropertySet()
+ */
+public class AccumuloConfigurationIsPropertySetTest extends WithTestNames {
+
+  private static final Set<Property> ALL_PROPERTIES = 
Set.of(Property.values());
+  private static final Logger log =
+      LoggerFactory.getLogger(AccumuloConfigurationIsPropertySetTest.class);
+  private static final InstanceId instanceId = 
InstanceId.of(UUID.randomUUID());
+
+  private final SystemPropKey sysPropKey = SystemPropKey.of(instanceId);
+  private final ArrayList<Object> mocks = new ArrayList<>();
+
+  private ZooPropStore propStore;
+  private ServerContext context;
+
+  @BeforeEach
+  public void setupMocks() {
+    propStore = createMock(ZooPropStore.class);
+    propStore.registerAsListener(anyObject(), anyObject());
+    expectLastCall().anyTimes();
+
+    context = getMockContextWithPropStore(instanceId, null, propStore);
+    SiteConfiguration siteConfig = SiteConfiguration.empty().build();
+    expect(context.getSiteConfiguration()).andReturn(siteConfig).anyTimes();
+  }
+
+  private void readyMocks(Object... mocksToReplay) {
+    mocks.addAll(Arrays.asList(mocksToReplay));
+    replay(mocksToReplay);
+  }
+
+  @AfterEach
+  public void verifyMocks() {
+    verify(mocks.toArray());
+  }
+
+  private static void verifyIsSet(AccumuloConfiguration conf, Set<Property> 
expectIsSet,
+      Set<Property> expectNotSet, Predicate<Property> isSetFunction) {
+    var notSetButShouldBe = 
expectIsSet.stream().filter(isSetFunction.negate()).collect(toSet());
+    var setButShouldNotBe = 
expectNotSet.stream().filter(isSetFunction).collect(toSet());
+    assertTrue(notSetButShouldBe.isEmpty(),
+        "Properties that should be set but are not: " + notSetButShouldBe);
+    assertTrue(setButShouldNotBe.isEmpty(),
+        "Properties that should not be set but are: " + setButShouldNotBe);
+  }
+
+  private static Predicate<Property> inGetProperties(AccumuloConfiguration 
conf) {
+    Map<String,String> propsMap = new HashMap<>();
+    conf.getProperties(propsMap, x -> true);
+    return property -> propsMap.containsKey(property.getKey());
+  }
+
+  private static Map<String,String> setToMap(Set<Property> props) {
+    return props.stream().collect(toMap(Property::getKey, 
Property::getDefaultValue));
+  }
+
+  @Test
+  public void testConfigurationCopy() {
+    var shouldBeSet = Set.of(TABLE_BLOOM_SIZE, GC_PORT);
+    var shouldNotBeSet = Sets.difference(ALL_PROPERTIES, shouldBeSet);
+    assertFalse(shouldNotBeSet.isEmpty());
+
+    var conf = new ConfigurationCopy(setToMap(shouldBeSet));
+
+    verifyIsSet(conf, shouldBeSet, shouldNotBeSet, inGetProperties(conf));
+
+    // verify using isPropertySet
+    verifyIsSet(conf, shouldBeSet, shouldNotBeSet, conf::isPropertySet);
+  }
+
+  @Test
+  public void testDefaultConfiguration() {
+    // isPropertySet should always be false since users can't set anything on 
DefaultConfiguration
+    var shouldBeSet = Set.<Property>of();
+    var shouldNotBeSet = new HashSet<>(ALL_PROPERTIES);
+
+    var conf = DefaultConfiguration.getInstance();
+
+    // verify using isPropertySet
+    verifyIsSet(conf, shouldBeSet, shouldNotBeSet, conf::isPropertySet);
+  }
+
+  @Test
+  public void testNamespaceConfiguration() {
+    var namespaceId = NamespaceId.of("namespace");
+    var nsPropKey = NamespacePropKey.of(instanceId, namespaceId);
+
+    var setOnParent = Set.of(TABLE_BLOOM_SIZE);
+    var parent = new ConfigurationCopy(setToMap(setOnParent));
+
+    var setOnNamespace = Set.of(INSTANCE_SECRET);
+    var nsProps = new VersionedProperties(123, Instant.now(), 
setToMap(setOnNamespace));
+    expect(propStore.get(eq(nsPropKey))).andReturn(nsProps).once();
+
+    readyMocks(context, propStore);
+
+    var namespaceConfig = new NamespaceConfiguration(context, namespaceId, 
parent);
+
+    var shouldBeSet = new HashSet<Property>();
+    shouldBeSet.addAll(setOnParent);
+    shouldBeSet.addAll(setOnNamespace);
+    assertFalse(shouldBeSet.isEmpty());
+    var shouldNotBeSet = Sets.difference(ALL_PROPERTIES, shouldBeSet);
+    assertFalse(shouldNotBeSet.isEmpty());
+
+    verifyIsSet(namespaceConfig, shouldBeSet, shouldNotBeSet, 
inGetProperties(namespaceConfig));
+
+    // verify using isPropertySet
+    verifyIsSet(namespaceConfig, shouldBeSet, shouldNotBeSet, 
namespaceConfig::isPropertySet);
+  }
+
+  @Test
+  public void testSiteConfiguration() throws IOException {
+    var shouldBeSet = Set.of(INSTANCE_ZK_HOST, INSTANCE_SECRET, 
MANAGER_BULK_TSERVER_REGEX);
+    var shouldNotBeSet = Sets.difference(ALL_PROPERTIES, shouldBeSet);
+    assertFalse(shouldNotBeSet.isEmpty());
+
+    var conf = 
SiteConfiguration.empty().withOverrides(setToMap(shouldBeSet)).build();
+
+    // verify properties are in the object without using defaults
+    Map<String,String> propsMap = new HashMap<>();
+    conf.getProperties(propsMap, x -> true, false);
+    Predicate<Property> mapContainsProp = property -> 
propsMap.containsKey(property.getKey());
+    verifyIsSet(conf, shouldBeSet, shouldNotBeSet, mapContainsProp);
+
+    // verify using isPropertySet
+    verifyIsSet(conf, shouldBeSet, shouldNotBeSet, conf::isPropertySet);
+  }
+
+  @Test
+  public void testSystemConfiguration() {
+    var setOnSystem = Set.of(GC_PORT, TSERV_SCAN_MAX_OPENFILES);
+    var sysProps = new VersionedProperties(1, Instant.now(), 
setToMap(setOnSystem));
+    expect(propStore.get(eq(sysPropKey))).andReturn(sysProps).once();
+
+    readyMocks(context, propStore);
+
+    var setOnParent = Set.of(TABLE_BLOOM_SIZE);
+    var parent = new ConfigurationCopy(setToMap(setOnParent));
+
+    var shouldBeSet = new HashSet<Property>();
+    shouldBeSet.addAll(setOnSystem);
+    shouldBeSet.addAll(setOnParent);
+    assertFalse(shouldBeSet.isEmpty());
+    var shouldNotBeSet = Sets.difference(ALL_PROPERTIES, shouldBeSet);
+    assertFalse(shouldNotBeSet.isEmpty());
+
+    var conf = new SystemConfiguration(context, sysPropKey, parent);
+
+    verifyIsSet(conf, shouldBeSet, shouldNotBeSet, inGetProperties(conf));
+    // these get added from the constructor via RuntimeFixedProperties and get 
checked in the
+    // isPropertySet impl; adding these to the expected list is a workaround 
until
+    // https://github.com/apache/accumulo/issues/3529 is fixed
+    shouldBeSet.addAll(Property.fixedProperties);
+
+    // verify using isPropertySet
+    verifyIsSet(conf, shouldBeSet, shouldNotBeSet, conf::isPropertySet);
+  }
+
+  @Test
+  public void testTableConfiguration() {
+    var namespaceId = NamespaceId.of("namespace");
+    var nsPropKey = NamespacePropKey.of(instanceId, namespaceId);
+
+    var tableId = TableId.of("3");
+    var tablePropKey = TablePropKey.of(instanceId, tableId);
+
+    var setOnNamespace = Set.of(TABLE_FILE_MAX);
+    var nsProps = new VersionedProperties(2, Instant.now(), 
setToMap(setOnNamespace));
+    expect(propStore.get(eq(nsPropKey))).andReturn(nsProps).once();
+
+    var setOnTable = Set.of(TABLE_BLOOM_ENABLED);
+    var tableProps = new VersionedProperties(3, Instant.now(), 
setToMap(setOnTable));
+    expect(propStore.get(eq(tablePropKey))).andReturn(tableProps).once();
+
+    readyMocks(context, propStore);
+
+    var setOnSystem = Set.of(TABLE_BLOOM_SIZE, TABLE_DURABILITY);
+    var sysConfig = new ConfigurationCopy(setToMap(setOnSystem));
+
+    var namespaceConfig = new NamespaceConfiguration(context, namespaceId, 
sysConfig);
+    var tableConfig = new TableConfiguration(context, tableId, 
namespaceConfig);
+
+    var shouldBeSet = new HashSet<Property>();
+    shouldBeSet.addAll(setOnSystem);
+    shouldBeSet.addAll(setOnNamespace);
+    shouldBeSet.addAll(setOnTable);
+    assertFalse(shouldBeSet.isEmpty());
+    var shouldNotBeSet = Sets.difference(ALL_PROPERTIES, shouldBeSet);
+    assertFalse(shouldNotBeSet.isEmpty());
+
+    verifyIsSet(tableConfig, shouldBeSet, shouldNotBeSet, 
inGetProperties(tableConfig));
+
+    // verify using isPropertySet
+    verifyIsSet(tableConfig, shouldBeSet, shouldNotBeSet, 
tableConfig::isPropertySet);
+  }
+
+  @Test
+  public void testZooBasedConfiguration() {
+    var setOnSystem = Set.of(GC_PORT);
+    var sysProps = new VersionedProperties(1, Instant.now(), 
setToMap(setOnSystem));
+    expect(propStore.get(eq(sysPropKey))).andReturn(sysProps).once();
+
+    readyMocks(context, propStore);
+
+    var setOnParent = Set.of(TABLE_BLOOM_SIZE);
+    var parent = new ConfigurationCopy(setToMap(setOnParent));
+
+    var shouldBeSet = new HashSet<Property>();
+    shouldBeSet.addAll(setOnSystem);
+    shouldBeSet.addAll(setOnParent);
+    assertFalse(shouldBeSet.isEmpty());
+    var shouldNotBeSet = Sets.difference(ALL_PROPERTIES, shouldBeSet);
+    assertFalse(shouldNotBeSet.isEmpty());
+
+    var conf = new ZooBasedConfiguration(log, context, sysPropKey, parent);
+
+    verifyIsSet(conf, shouldBeSet, shouldNotBeSet, inGetProperties(conf));
+
+    // verify using isPropertySet
+    verifyIsSet(conf, shouldBeSet, shouldNotBeSet, conf::isPropertySet);
+  }
+
+}

Reply via email to