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

cwylie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new fd20bbd30e Fix another infinite loop and remove Mockito usage (#14493)
fd20bbd30e is described below

commit fd20bbd30ecee969fd3f38cbe1d45de7d763f531
Author: imply-cheddar <[email protected]>
AuthorDate: Wed Jun 28 13:49:27 2023 +0900

    Fix another infinite loop and remove Mockito usage (#14493)
    
    * Fix another infinite loop and remove Mockito usage
    
    The ConfigManager objects were `started()` without ever being
    stopped.  This scheduled a poll call that never-ended, to make
    matters worse, the poll interval was set to 0 ms, making an
    infinite poll with 0 sleep, i.e. an infinite loop.
    
    Also introduce test classes and remove usage of mocks
    
    * Checkstyle
---
 .../org/apache/druid/audit/TestAuditManager.java   |  71 ++++++++
 .../druid/common/config/ConfigManagerTest.java     | 182 +++++++++++++--------
 .../common/config/TestConfigManagerConfig.java     |  40 +++++
 .../metadata/TestMetadataStorageConnector.java     |  92 +++++++++++
 .../metadata/TestMetadataStorageTablesConfig.java  |  43 +++++
 5 files changed, 361 insertions(+), 67 deletions(-)

diff --git 
a/processing/src/test/java/org/apache/druid/audit/TestAuditManager.java 
b/processing/src/test/java/org/apache/druid/audit/TestAuditManager.java
new file mode 100644
index 0000000000..fd34330a68
--- /dev/null
+++ b/processing/src/test/java/org/apache/druid/audit/TestAuditManager.java
@@ -0,0 +1,71 @@
+/*
+ * 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.druid.audit;
+
+import org.apache.druid.common.config.ConfigSerde;
+import org.joda.time.Interval;
+import org.skife.jdbi.v2.Handle;
+
+import java.util.List;
+
+public class TestAuditManager implements AuditManager
+{
+  @Override
+  public <T> void doAudit(String key, String type, AuditInfo auditInfo, T 
payload, ConfigSerde<T> configSerde)
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void doAudit(AuditEntry auditEntry, Handle handler)
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public List<AuditEntry> fetchAuditHistory(String key, String type, Interval 
interval)
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public List<AuditEntry> fetchAuditHistory(String type, Interval interval)
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public List<AuditEntry> fetchAuditHistory(String key, String type, int limit)
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public List<AuditEntry> fetchAuditHistory(String type, int limit)
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public int removeAuditLogsOlderThan(long timestamp)
+  {
+    throw new UnsupportedOperationException();
+  }
+}
diff --git 
a/processing/src/test/java/org/apache/druid/common/config/ConfigManagerTest.java
 
b/processing/src/test/java/org/apache/druid/common/config/ConfigManagerTest.java
index 9705939991..2f58147e77 100644
--- 
a/processing/src/test/java/org/apache/druid/common/config/ConfigManagerTest.java
+++ 
b/processing/src/test/java/org/apache/druid/common/config/ConfigManagerTest.java
@@ -25,26 +25,19 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.base.Suppliers;
 import org.apache.druid.audit.AuditManager;
+import org.apache.druid.audit.TestAuditManager;
 import org.apache.druid.metadata.MetadataCASUpdate;
 import org.apache.druid.metadata.MetadataStorageConnector;
 import org.apache.druid.metadata.MetadataStorageTablesConfig;
-import org.joda.time.Period;
+import org.apache.druid.metadata.TestMetadataStorageConnector;
+import org.apache.druid.metadata.TestMetadataStorageTablesConfig;
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatchers;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.junit.MockitoJUnitRunner;
 
 import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
-
-@RunWith(MockitoJUnitRunner.class)
+@SuppressWarnings("ALL")
 public class ConfigManagerTest
 {
   private static final String CONFIG_KEY = "configX";
@@ -52,33 +45,42 @@ public class ConfigManagerTest
   private static final byte[] OLD_CONFIG = {1, 2, 3};
   private static final TestConfig NEW_CONFIG = new TestConfig("2", "y", 2);
 
-  @Mock
-  private MetadataStorageConnector mockDbConnector;
-
-  @Mock
-  private MetadataStorageTablesConfig mockMetadataStorageTablesConfig;
-
-  @Mock
+  private MetadataStorageConnector dbConnector;
+  private MetadataStorageTablesConfig metadataStorageTablesConfig;
   private AuditManager mockAuditManager;
-
-  @Mock
-  private ConfigManagerConfig mockConfigManagerConfig;
+  private TestConfigManagerConfig configManagerConfig;
 
   private ConfigSerde<TestConfig> configConfigSerdeFromClass;
   private ConfigManager configManager;
   private JacksonConfigManager jacksonConfigManager;
 
-  @Before
   public void setup()
   {
-    
when(mockMetadataStorageTablesConfig.getConfigTable()).thenReturn(TABLE_NAME);
-    when(mockConfigManagerConfig.getPollDuration()).thenReturn(new Period());
-    configManager = new ConfigManager(mockDbConnector, 
Suppliers.ofInstance(mockMetadataStorageTablesConfig), 
Suppliers.ofInstance(mockConfigManagerConfig));
+    setup(new TestMetadataStorageConnector());
+  }
+
+  public void setup(TestMetadataStorageConnector dbConnector)
+  {
+    this.dbConnector = dbConnector;
+    metadataStorageTablesConfig = new TestMetadataStorageTablesConfig()
+    {
+      @Override
+      public String getConfigTable()
+      {
+        return TABLE_NAME;
+      }
+    };
+    configManagerConfig = new TestConfigManagerConfig();
+    configManager = new ConfigManager(
+        this.dbConnector,
+        Suppliers.ofInstance(metadataStorageTablesConfig),
+        Suppliers.ofInstance(configManagerConfig)
+    );
     jacksonConfigManager = new JacksonConfigManager(
         configManager,
         new ObjectMapper(),
         new 
ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL),
-        mockAuditManager
+        new TestAuditManager()
     );
     configConfigSerdeFromClass = jacksonConfigManager.create(TestConfig.class, 
null);
   }
@@ -86,6 +88,7 @@ public class ConfigManagerTest
   @Test
   public void testSetNewObjectIsNull()
   {
+    setup();
     ConfigManager.SetResult setResult = configManager.set(CONFIG_KEY, 
configConfigSerdeFromClass, null);
     Assert.assertFalse(setResult.isOk());
     Assert.assertFalse(setResult.isRetryable());
@@ -95,6 +98,7 @@ public class ConfigManagerTest
   @Test
   public void testSetConfigManagerNotStarted()
   {
+    setup();
     ConfigManager.SetResult setResult = configManager.set(CONFIG_KEY, 
configConfigSerdeFromClass, NEW_CONFIG);
     Assert.assertFalse(setResult.isOk());
     Assert.assertFalse(setResult.isRetryable());
@@ -104,56 +108,100 @@ public class ConfigManagerTest
   @Test
   public void testSetOldObjectNullShouldInsertWithoutSwap()
   {
-    configManager.start();
-    ConfigManager.SetResult setResult = configManager.set(CONFIG_KEY, 
configConfigSerdeFromClass, null, NEW_CONFIG);
-    Assert.assertTrue(setResult.isOk());
-    Mockito.verify(mockDbConnector).insertOrUpdate(
-        ArgumentMatchers.eq(TABLE_NAME),
-        ArgumentMatchers.anyString(),
-        ArgumentMatchers.anyString(),
-        ArgumentMatchers.eq(CONFIG_KEY),
-        ArgumentMatchers.any(byte[].class)
-    );
-    Mockito.verifyNoMoreInteractions(mockDbConnector);
+    final AtomicBoolean called = new AtomicBoolean();
+    setup(new TestMetadataStorageConnector()
+    {
+
+      @Override
+      public Void insertOrUpdate(String tableName, String keyColumn, String 
valueColumn, String key, byte[] value)
+      {
+        Assert.assertFalse(called.getAndSet(true));
+        Assert.assertEquals(TABLE_NAME, tableName);
+        Assert.assertEquals(CONFIG_KEY, key);
+        return null;
+      }
+    });
+
+    try {
+      configManager.start();
+      ConfigManager.SetResult setResult = configManager.set(CONFIG_KEY, 
configConfigSerdeFromClass, null, NEW_CONFIG);
+      Assert.assertTrue(setResult.isOk());
+      Assert.assertTrue(called.get());
+    }
+    finally {
+      configManager.stop();
+    }
   }
 
   @Test
   public void testSetOldObjectNotNullShouldSwap()
   {
-    when(mockConfigManagerConfig.isEnableCompareAndSwap()).thenReturn(true);
-    when(mockDbConnector.compareAndSwap(any(List.class))).thenReturn(true);
-    final ArgumentCaptor<List<MetadataCASUpdate>> updateCaptor = 
ArgumentCaptor.forClass(List.class);
-    configManager.start();
-    ConfigManager.SetResult setResult = configManager.set(CONFIG_KEY, 
configConfigSerdeFromClass, OLD_CONFIG, NEW_CONFIG);
-    Assert.assertTrue(setResult.isOk());
-    Mockito.verify(mockDbConnector).compareAndSwap(
-        updateCaptor.capture()
-    );
-    Mockito.verifyNoMoreInteractions(mockDbConnector);
-    Assert.assertEquals(1, updateCaptor.getValue().size());
-    Assert.assertEquals(TABLE_NAME, 
updateCaptor.getValue().get(0).getTableName());
-    Assert.assertEquals(MetadataStorageConnector.CONFIG_TABLE_KEY_COLUMN, 
updateCaptor.getValue().get(0).getKeyColumn());
-    Assert.assertEquals(MetadataStorageConnector.CONFIG_TABLE_VALUE_COLUMN, 
updateCaptor.getValue().get(0).getValueColumn());
-    Assert.assertEquals(CONFIG_KEY, updateCaptor.getValue().get(0).getKey());
-    Assert.assertArrayEquals(OLD_CONFIG, 
updateCaptor.getValue().get(0).getOldValue());
-    Assert.assertArrayEquals(configConfigSerdeFromClass.serialize(NEW_CONFIG), 
updateCaptor.getValue().get(0).getNewValue());
+    final AtomicBoolean called = new AtomicBoolean();
+    setup(new TestMetadataStorageConnector()
+    {
+      @Override
+      public boolean compareAndSwap(List<MetadataCASUpdate> updates)
+      {
+        Assert.assertFalse(called.getAndSet(true));
+        Assert.assertEquals(1, updates.size());
+        final MetadataCASUpdate singularUpdate = updates.get(0);
+        Assert.assertEquals(TABLE_NAME, singularUpdate.getTableName());
+        Assert.assertEquals(MetadataStorageConnector.CONFIG_TABLE_KEY_COLUMN, 
singularUpdate.getKeyColumn());
+        
Assert.assertEquals(MetadataStorageConnector.CONFIG_TABLE_VALUE_COLUMN, 
singularUpdate.getValueColumn());
+        Assert.assertEquals(CONFIG_KEY, singularUpdate.getKey());
+        Assert.assertArrayEquals(OLD_CONFIG, singularUpdate.getOldValue());
+        
Assert.assertArrayEquals(configConfigSerdeFromClass.serialize(NEW_CONFIG), 
singularUpdate.getNewValue());
+        return true;
+      }
+    });
+    try {
+      configManager.start();
+      ConfigManager.SetResult setResult = configManager.set(
+          CONFIG_KEY,
+          configConfigSerdeFromClass,
+          OLD_CONFIG,
+          NEW_CONFIG
+      );
+      Assert.assertTrue(setResult.isOk());
+      Assert.assertTrue(called.get());
+    }
+    finally {
+      configManager.stop();
+    }
   }
 
   @Test
   public void 
testSetOldObjectNotNullButCompareAndSwapDisabledShouldInsertWithoutSwap()
   {
-    when(mockConfigManagerConfig.isEnableCompareAndSwap()).thenReturn(false);
-    configManager.start();
-    ConfigManager.SetResult setResult = configManager.set(CONFIG_KEY, 
configConfigSerdeFromClass, OLD_CONFIG, NEW_CONFIG);
-    Assert.assertTrue(setResult.isOk());
-    Mockito.verify(mockDbConnector).insertOrUpdate(
-        ArgumentMatchers.eq(TABLE_NAME),
-        ArgumentMatchers.anyString(),
-        ArgumentMatchers.anyString(),
-        ArgumentMatchers.eq(CONFIG_KEY),
-        ArgumentMatchers.any(byte[].class)
-    );
-    Mockito.verifyNoMoreInteractions(mockDbConnector);
+    final AtomicBoolean called = new AtomicBoolean();
+
+    setup(new TestMetadataStorageConnector()
+    {
+      @Override
+      public Void insertOrUpdate(String tableName, String keyColumn, String 
valueColumn, String key, byte[] value)
+      {
+        Assert.assertFalse(called.getAndSet(true));
+        Assert.assertEquals(TABLE_NAME, tableName);
+        Assert.assertEquals(CONFIG_KEY, key);
+        return null;
+      }
+    });
+    configManagerConfig.enableCompareAndSwap = false;
+
+    try {
+      configManager.start();
+      ConfigManager.SetResult setResult = configManager.set(
+          CONFIG_KEY,
+          configConfigSerdeFromClass,
+          OLD_CONFIG,
+          NEW_CONFIG
+      );
+      Assert.assertTrue(setResult.isOk());
+      Assert.assertTrue(called.get());
+    }
+    finally {
+      configManager.stop();
+    }
   }
 
   static class TestConfig
diff --git 
a/processing/src/test/java/org/apache/druid/common/config/TestConfigManagerConfig.java
 
b/processing/src/test/java/org/apache/druid/common/config/TestConfigManagerConfig.java
new file mode 100644
index 0000000000..69ff82ca2a
--- /dev/null
+++ 
b/processing/src/test/java/org/apache/druid/common/config/TestConfigManagerConfig.java
@@ -0,0 +1,40 @@
+/*
+ * 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.druid.common.config;
+
+import org.joda.time.Period;
+
+public class TestConfigManagerConfig extends ConfigManagerConfig
+{
+  public Period period = null;
+  public boolean enableCompareAndSwap = true;
+
+  @Override
+  public Period getPollDuration()
+  {
+    return period == null ? super.getPollDuration() : period;
+  }
+
+  @Override
+  public boolean isEnableCompareAndSwap()
+  {
+    return enableCompareAndSwap;
+  }
+}
diff --git 
a/processing/src/test/java/org/apache/druid/metadata/TestMetadataStorageConnector.java
 
b/processing/src/test/java/org/apache/druid/metadata/TestMetadataStorageConnector.java
new file mode 100644
index 0000000000..028a9d5cc0
--- /dev/null
+++ 
b/processing/src/test/java/org/apache/druid/metadata/TestMetadataStorageConnector.java
@@ -0,0 +1,92 @@
+/*
+ * 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.druid.metadata;
+
+import javax.annotation.Nullable;
+
+public class TestMetadataStorageConnector implements MetadataStorageConnector
+{
+  @Override
+  public Void insertOrUpdate(String tableName, String keyColumn, String 
valueColumn, String key, byte[] value)
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Nullable
+  @Override
+  public byte[] lookup(String tableName, String keyColumn, String valueColumn, 
String key)
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void createDataSourceTable()
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void createPendingSegmentsTable()
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void createSegmentTable()
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void createRulesTable()
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void createConfigTable()
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void createTaskTables()
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void createAuditTable()
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void createSupervisorsTable()
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void deleteAllRecords(String tableName)
+  {
+    throw new UnsupportedOperationException();
+  }
+}
diff --git 
a/processing/src/test/java/org/apache/druid/metadata/TestMetadataStorageTablesConfig.java
 
b/processing/src/test/java/org/apache/druid/metadata/TestMetadataStorageTablesConfig.java
new file mode 100644
index 0000000000..693b36ce24
--- /dev/null
+++ 
b/processing/src/test/java/org/apache/druid/metadata/TestMetadataStorageTablesConfig.java
@@ -0,0 +1,43 @@
+/*
+ * 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.druid.metadata;
+
+/**
+ * A config object for tests, use by overriding the specific getter methods 
and returning what you want
+ */
+public class TestMetadataStorageTablesConfig extends 
MetadataStorageTablesConfig
+{
+  public TestMetadataStorageTablesConfig()
+  {
+    super(
+        "test",
+        null,
+        null,
+        null,
+        null,
+        null,
+        null,
+        null,
+        null,
+        null,
+        null
+    );
+  }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to