You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@asterixdb.apache.org by AsterixDB Code Review <do...@asterix-gerrit.ics.uci.edu> on 2021/05/14 15:43:15 UTC
Change in asterixdb[mad-hatter]: [NO ISSUE][TEST] Improve ExceptionTest performance
From Michael Blow <mb...@apache.org>:
Michael Blow has uploaded this change for review. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/11463 )
Change subject: [NO ISSUE][TEST] Improve ExceptionTest performance
......................................................................
[NO ISSUE][TEST] Improve ExceptionTest performance
Change-Id: I3f478e29cd3e500775d63c77d1cde2f95c42c79a
---
M asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/ExceptionTest.java
1 file changed, 74 insertions(+), 50 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb refs/changes/63/11463/1
diff --git a/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/ExceptionTest.java b/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/ExceptionTest.java
index 91752f7..756572c 100644
--- a/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/ExceptionTest.java
+++ b/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/ExceptionTest.java
@@ -30,13 +30,17 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Stream;
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.om.functions.BuiltinFunctionInfo;
import org.apache.asterix.om.functions.BuiltinFunctions;
import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.types.IAType;
import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableInt;
import org.apache.commons.lang3.mutable.MutableObject;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
@@ -45,6 +49,7 @@
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import org.apache.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionVisitor;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -54,6 +59,9 @@
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
@@ -173,6 +181,7 @@
return tests;
}
+
@Test
public void test() throws Exception {
// If a type computer is not found in the map, then it is not used by any function
@@ -195,6 +204,7 @@
(typeComputerMaxArgs > MAXIMUM_ARGUMENTS_ALLOWED || typeComputerMaxArgs == FunctionIdentifier.VARARGS)
? MAXIMUM_ARGUMENTS_ALLOWED : typeComputerMaxArgs;
int numberOfCombinations = (int) Math.pow(ATypeTag.values().length, numberOfArguments);
+ LOGGER.info("{} has {} combinations", clazz.getSimpleName(), numberOfCombinations);
Object[] opaqueParameters = new Object[numberOfArguments];
List<Mutable<ILogicalExpression>> argumentsList = new ArrayList<>(numberOfArguments);
@@ -202,64 +212,69 @@
opaqueParameters[i] = BuiltinType.ANY;
}
+ List<IResultTypeComputer> instances = new ArrayList<>();
+ Field[] fields = clazz.getFields();
+ for (Field field : fields) {
+ if (field.getType().equals(clazz)) {
+ instances.add((IResultTypeComputer) field.get(null));
+ }
+ }
+
+ // Type environment and metadata provider
+ IVariableTypeEnvironment typeEnv = mock(IVariableTypeEnvironment.class);
+ IMetadataProvider metadataProvider = mock(IMetadataProvider.class);
+
+ // Function identifier
+ FunctionIdentifier functionIdentifier = mock(FunctionIdentifier.class);
+ when(functionIdentifier.getName()).thenReturn("testFunction");
+
+ // Function call expression
+ AbstractFunctionCallExpression functionCallExpression = mock(AbstractFunctionCallExpression.class);
+ when(functionCallExpression.getFunctionIdentifier()).thenReturn(functionIdentifier);
+ when(functionCallExpression.getOpaqueParameters()).thenReturn(opaqueParameters);
+ MutableInt indexHolder = new MutableInt(0);
+ Map<ATypeTag,ILogicalExpression> typeArgumentMap = new HashMap<>();
+ for (ATypeTag tag : ATypeTag.values()) {
+ if (tag != null) {
+ // Set the types
+ IAType iaType = mock(IAType.class);
+ when(iaType.getTypeTag()).thenReturn(tag);
+
+ ILogicalExpression argument = mock(ILogicalExpression.class);
+ when(typeEnv.getType(argument)).thenReturn(iaType);
+ typeArgumentMap.put(tag, argument);
+ }
+ }
+
+ when(functionCallExpression.getArguments()).thenAnswer((Answer<List<Mutable<ILogicalExpression>>>) invocation -> {
+ for (int argIndex = 0; argIndex < numberOfArguments; ++argIndex) {
+ int base = (int) Math.pow(ATypeTag.values().length, argIndex);
+ int serializedTypeTag = (indexHolder.getValue() / base) % ATypeTag.values().length + 1;
+
+ ATypeTag typeTag = ATypeTag.VALUE_TYPE_MAPPING[serializedTypeTag];
+ if (typeTag == null) {
+ // If any tags have been removed or are missing, replace them with any
+ typeTag = ATypeTag.ANY;
+ }
+ // Add argument to the arguments list
+ argumentsList.add(new MutableObject<>(typeArgumentMap.get(typeTag)));
+ }
+ return argumentsList;
+ });
+
// Sets arguments for the mocked function expression.
for (int index = 0; index < numberOfCombinations; ++index) {
-
argumentsList.clear();
-
- // Type environment and metadata provider
- IVariableTypeEnvironment typeEnv = mock(IVariableTypeEnvironment.class);
- IMetadataProvider metadataProvider = mock(IMetadataProvider.class);
-
- // Function identifier
- FunctionIdentifier functionIdentifier = mock(FunctionIdentifier.class);
- when(functionIdentifier.getName()).thenReturn("testFunction");
-
- // Function call expression
- AbstractFunctionCallExpression functionCallExpression = mock(AbstractFunctionCallExpression.class);
- when(functionCallExpression.getFunctionIdentifier()).thenReturn(functionIdentifier);
-
try {
- for (int argIndex = 0; argIndex < numberOfArguments; ++argIndex) {
- int base = (int) Math.pow(ATypeTag.values().length, argIndex);
- int serializedTypeTag = (index / base) % ATypeTag.values().length + 1;
-
- ATypeTag typeTag = ATypeTag.VALUE_TYPE_MAPPING[serializedTypeTag];
- if (typeTag == null) {
- // If any tags have been removed or are missing, replace them with any
- typeTag = ATypeTag.ANY;
- }
-
- // Set the types
- IAType iaType = mock(IAType.class);
- when(iaType.getTypeTag()).thenReturn(typeTag);
-
- ILogicalExpression argument = mock(ILogicalExpression.class);
- when(typeEnv.getType(argument)).thenReturn(iaType);
-
- // Add argument to the arguments list
- argumentsList.add(new MutableObject<>(argument));
- }
-
- // Sets up arguments for the mocked expression.
- when(functionCallExpression.getArguments()).thenReturn(argumentsList);
- when(functionCallExpression.getOpaqueParameters()).thenReturn(opaqueParameters);
-
+ indexHolder.setValue(index);
// Invokes a type computer.
- IResultTypeComputer instance;
- Field[] fields = clazz.getFields();
-
- for (Field field : fields) {
- if (field.getType().equals(clazz)) {
- instance = (IResultTypeComputer) field.get(null);
- instance.computeType(functionCallExpression, typeEnv, metadataProvider);
- }
+ for (IResultTypeComputer instance : instances) {
+ instance.computeType(functionCallExpression, typeEnv, metadataProvider);
}
} catch (AlgebricksException ae) {
- String msg = ae.getMessage();
- if (msg.startsWith("ASX")) {
+ if (ae.getComponent().equals(ErrorCode.ASTERIX)) {
// Verifies the error code.
- int errorCode = Integer.parseInt(msg.substring(3, 7));
+ int errorCode = ae.getErrorCode();
Assert.assertTrue(errorCode >= 1000 && errorCode < 2000);
} else {
// Any root-level compilation exceptions thrown from type computers should have an error code.
@@ -269,5 +284,14 @@
// Do nothing
}
}
+ typeArgumentMap.values().stream().map(arg -> {
+ try {
+ return (IAType)(typeEnv.getType(arg));
+ } catch (AlgebricksException e) {
+ throw new IllegalStateException(e);
+ }
+ }).forEach(Mockito::reset);
+ typeArgumentMap.values().forEach(Mockito::reset);
+ Mockito.reset(typeEnv, metadataProvider, functionIdentifier, functionCallExpression);
}
}
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/11463
To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-Project: asterixdb
Gerrit-Branch: mad-hatter
Gerrit-Change-Id: I3f478e29cd3e500775d63c77d1cde2f95c42c79a
Gerrit-Change-Number: 11463
Gerrit-PatchSet: 1
Gerrit-Owner: Michael Blow <mb...@apache.org>
Gerrit-MessageType: newchange
Change in asterixdb[mad-hatter]: [NO ISSUE][TEST] Improve ExceptionTest performance
Posted by AsterixDB Code Review <do...@asterix-gerrit.ics.uci.edu>.
From Jenkins <je...@fulliautomatix.ics.uci.edu>:
Jenkins has posted comments on this change. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/11463 )
Change subject: [NO ISSUE][TEST] Improve ExceptionTest performance
......................................................................
Patch Set 1: Integration-Tests+1
Integration Tests Successful
https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-integration-tests/11980/ : SUCCESS
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/11463
To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-Project: asterixdb
Gerrit-Branch: mad-hatter
Gerrit-Change-Id: I3f478e29cd3e500775d63c77d1cde2f95c42c79a
Gerrit-Change-Number: 11463
Gerrit-PatchSet: 1
Gerrit-Owner: Michael Blow <mb...@apache.org>
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-CC: Anon. E. Moose #1000171
Gerrit-Comment-Date: Fri, 14 May 2021 16:43:23 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment
Change in asterixdb[mad-hatter]: [NO ISSUE][TEST] Improve ExceptionTest performance
Posted by AsterixDB Code Review <do...@asterix-gerrit.ics.uci.edu>.
From Michael Blow <mb...@apache.org>:
Michael Blow has uploaded this change for review. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/11463 )
Change subject: [NO ISSUE][TEST] Improve ExceptionTest performance
......................................................................
[NO ISSUE][TEST] Improve ExceptionTest performance
Change-Id: I3f478e29cd3e500775d63c77d1cde2f95c42c79a
---
M asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/ExceptionTest.java
1 file changed, 74 insertions(+), 50 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb refs/changes/63/11463/1
diff --git a/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/ExceptionTest.java b/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/ExceptionTest.java
index 91752f7..756572c 100644
--- a/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/ExceptionTest.java
+++ b/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/typecomputer/ExceptionTest.java
@@ -30,13 +30,17 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Stream;
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.om.functions.BuiltinFunctionInfo;
import org.apache.asterix.om.functions.BuiltinFunctions;
import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.types.IAType;
import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableInt;
import org.apache.commons.lang3.mutable.MutableObject;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
@@ -45,6 +49,7 @@
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import org.apache.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionVisitor;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -54,6 +59,9 @@
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
@@ -173,6 +181,7 @@
return tests;
}
+
@Test
public void test() throws Exception {
// If a type computer is not found in the map, then it is not used by any function
@@ -195,6 +204,7 @@
(typeComputerMaxArgs > MAXIMUM_ARGUMENTS_ALLOWED || typeComputerMaxArgs == FunctionIdentifier.VARARGS)
? MAXIMUM_ARGUMENTS_ALLOWED : typeComputerMaxArgs;
int numberOfCombinations = (int) Math.pow(ATypeTag.values().length, numberOfArguments);
+ LOGGER.info("{} has {} combinations", clazz.getSimpleName(), numberOfCombinations);
Object[] opaqueParameters = new Object[numberOfArguments];
List<Mutable<ILogicalExpression>> argumentsList = new ArrayList<>(numberOfArguments);
@@ -202,64 +212,69 @@
opaqueParameters[i] = BuiltinType.ANY;
}
+ List<IResultTypeComputer> instances = new ArrayList<>();
+ Field[] fields = clazz.getFields();
+ for (Field field : fields) {
+ if (field.getType().equals(clazz)) {
+ instances.add((IResultTypeComputer) field.get(null));
+ }
+ }
+
+ // Type environment and metadata provider
+ IVariableTypeEnvironment typeEnv = mock(IVariableTypeEnvironment.class);
+ IMetadataProvider metadataProvider = mock(IMetadataProvider.class);
+
+ // Function identifier
+ FunctionIdentifier functionIdentifier = mock(FunctionIdentifier.class);
+ when(functionIdentifier.getName()).thenReturn("testFunction");
+
+ // Function call expression
+ AbstractFunctionCallExpression functionCallExpression = mock(AbstractFunctionCallExpression.class);
+ when(functionCallExpression.getFunctionIdentifier()).thenReturn(functionIdentifier);
+ when(functionCallExpression.getOpaqueParameters()).thenReturn(opaqueParameters);
+ MutableInt indexHolder = new MutableInt(0);
+ Map<ATypeTag,ILogicalExpression> typeArgumentMap = new HashMap<>();
+ for (ATypeTag tag : ATypeTag.values()) {
+ if (tag != null) {
+ // Set the types
+ IAType iaType = mock(IAType.class);
+ when(iaType.getTypeTag()).thenReturn(tag);
+
+ ILogicalExpression argument = mock(ILogicalExpression.class);
+ when(typeEnv.getType(argument)).thenReturn(iaType);
+ typeArgumentMap.put(tag, argument);
+ }
+ }
+
+ when(functionCallExpression.getArguments()).thenAnswer((Answer<List<Mutable<ILogicalExpression>>>) invocation -> {
+ for (int argIndex = 0; argIndex < numberOfArguments; ++argIndex) {
+ int base = (int) Math.pow(ATypeTag.values().length, argIndex);
+ int serializedTypeTag = (indexHolder.getValue() / base) % ATypeTag.values().length + 1;
+
+ ATypeTag typeTag = ATypeTag.VALUE_TYPE_MAPPING[serializedTypeTag];
+ if (typeTag == null) {
+ // If any tags have been removed or are missing, replace them with any
+ typeTag = ATypeTag.ANY;
+ }
+ // Add argument to the arguments list
+ argumentsList.add(new MutableObject<>(typeArgumentMap.get(typeTag)));
+ }
+ return argumentsList;
+ });
+
// Sets arguments for the mocked function expression.
for (int index = 0; index < numberOfCombinations; ++index) {
-
argumentsList.clear();
-
- // Type environment and metadata provider
- IVariableTypeEnvironment typeEnv = mock(IVariableTypeEnvironment.class);
- IMetadataProvider metadataProvider = mock(IMetadataProvider.class);
-
- // Function identifier
- FunctionIdentifier functionIdentifier = mock(FunctionIdentifier.class);
- when(functionIdentifier.getName()).thenReturn("testFunction");
-
- // Function call expression
- AbstractFunctionCallExpression functionCallExpression = mock(AbstractFunctionCallExpression.class);
- when(functionCallExpression.getFunctionIdentifier()).thenReturn(functionIdentifier);
-
try {
- for (int argIndex = 0; argIndex < numberOfArguments; ++argIndex) {
- int base = (int) Math.pow(ATypeTag.values().length, argIndex);
- int serializedTypeTag = (index / base) % ATypeTag.values().length + 1;
-
- ATypeTag typeTag = ATypeTag.VALUE_TYPE_MAPPING[serializedTypeTag];
- if (typeTag == null) {
- // If any tags have been removed or are missing, replace them with any
- typeTag = ATypeTag.ANY;
- }
-
- // Set the types
- IAType iaType = mock(IAType.class);
- when(iaType.getTypeTag()).thenReturn(typeTag);
-
- ILogicalExpression argument = mock(ILogicalExpression.class);
- when(typeEnv.getType(argument)).thenReturn(iaType);
-
- // Add argument to the arguments list
- argumentsList.add(new MutableObject<>(argument));
- }
-
- // Sets up arguments for the mocked expression.
- when(functionCallExpression.getArguments()).thenReturn(argumentsList);
- when(functionCallExpression.getOpaqueParameters()).thenReturn(opaqueParameters);
-
+ indexHolder.setValue(index);
// Invokes a type computer.
- IResultTypeComputer instance;
- Field[] fields = clazz.getFields();
-
- for (Field field : fields) {
- if (field.getType().equals(clazz)) {
- instance = (IResultTypeComputer) field.get(null);
- instance.computeType(functionCallExpression, typeEnv, metadataProvider);
- }
+ for (IResultTypeComputer instance : instances) {
+ instance.computeType(functionCallExpression, typeEnv, metadataProvider);
}
} catch (AlgebricksException ae) {
- String msg = ae.getMessage();
- if (msg.startsWith("ASX")) {
+ if (ae.getComponent().equals(ErrorCode.ASTERIX)) {
// Verifies the error code.
- int errorCode = Integer.parseInt(msg.substring(3, 7));
+ int errorCode = ae.getErrorCode();
Assert.assertTrue(errorCode >= 1000 && errorCode < 2000);
} else {
// Any root-level compilation exceptions thrown from type computers should have an error code.
@@ -269,5 +284,14 @@
// Do nothing
}
}
+ typeArgumentMap.values().stream().map(arg -> {
+ try {
+ return (IAType)(typeEnv.getType(arg));
+ } catch (AlgebricksException e) {
+ throw new IllegalStateException(e);
+ }
+ }).forEach(Mockito::reset);
+ typeArgumentMap.values().forEach(Mockito::reset);
+ Mockito.reset(typeEnv, metadataProvider, functionIdentifier, functionCallExpression);
}
}
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/11463
To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-Project: asterixdb
Gerrit-Branch: mad-hatter
Gerrit-Change-Id: I3f478e29cd3e500775d63c77d1cde2f95c42c79a
Gerrit-Change-Number: 11463
Gerrit-PatchSet: 1
Gerrit-Owner: Michael Blow <mb...@apache.org>
Gerrit-MessageType: newchange
Change in asterixdb[mad-hatter]: [NO ISSUE][TEST] Improve ExceptionTest performance
Posted by AsterixDB Code Review <do...@asterix-gerrit.ics.uci.edu>.
Anon. E. Moose #1000171 has posted comments on this change. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/11463 )
Change subject: [NO ISSUE][TEST] Improve ExceptionTest performance
......................................................................
Patch Set 1:
Analytics Compatibility Compilation Successful
https://cbjenkins.page.link/WcehmUjnpXVoSJNe9 : SUCCESS
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/11463
To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-Project: asterixdb
Gerrit-Branch: mad-hatter
Gerrit-Change-Id: I3f478e29cd3e500775d63c77d1cde2f95c42c79a
Gerrit-Change-Number: 11463
Gerrit-PatchSet: 1
Gerrit-Owner: Michael Blow <mb...@apache.org>
Gerrit-CC: Anon. E. Moose #1000171
Gerrit-CC: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-Comment-Date: Fri, 14 May 2021 15:50:29 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
Gerrit-MessageType: comment
Change in asterixdb[mad-hatter]: [NO ISSUE][TEST] Improve ExceptionTest performance
Posted by AsterixDB Code Review <do...@asterix-gerrit.ics.uci.edu>.
Anon. E. Moose #1000171 has posted comments on this change. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/11463 )
Change subject: [NO ISSUE][TEST] Improve ExceptionTest performance
......................................................................
Patch Set 1: Contrib+1
Analytics Compatibility Tests Successful
https://cbjenkins.page.link/Nn7e7GTSbNAKrzoKA : SUCCESS
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/11463
To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-Project: asterixdb
Gerrit-Branch: mad-hatter
Gerrit-Change-Id: I3f478e29cd3e500775d63c77d1cde2f95c42c79a
Gerrit-Change-Number: 11463
Gerrit-PatchSet: 1
Gerrit-Owner: Michael Blow <mb...@apache.org>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-Comment-Date: Fri, 14 May 2021 17:34:33 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment