Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix : sorting rate metrics #102

Merged
merged 11 commits into from
Nov 22, 2021
Merged

fix : sorting rate metrics #102

merged 11 commits into from
Nov 22, 2021

Conversation

sarthak77
Copy link
Member

@sarthak77 sarthak77 commented Nov 19, 2021

On the service (backend) screen page, there is a rate column - error/s. After we moved the avgrate functionality to query-service, the sorting on this column is broken.

The reason it was broken, that avgrate function takes two arguments (column name, size). The second size argument is missing in order by expression. Priori, it was working fine as avgrate was translated to sum at the gateway service layer. And sum function needs only single column name argument.

As these rate columns are per second rate, for now, defaulting to PT1S as size for avgrate function to fix the regression.

@codecov
Copy link

codecov bot commented Nov 19, 2021

Codecov Report

Merging #102 (4d451f9) into main (cc5cdff) will increase coverage by 0.01%.
The diff coverage is 100.00%.

Impacted file tree graph

@@             Coverage Diff              @@
##               main     #102      +/-   ##
============================================
+ Coverage     82.47%   82.48%   +0.01%     
- Complexity      419      421       +2     
============================================
  Files            37       37              
  Lines          1603     1604       +1     
  Branches        168      169       +1     
============================================
+ Hits           1322     1323       +1     
  Misses          207      207              
  Partials         74       74              
Flag Coverage Δ
integration 82.48% <100.00%> (+0.01%) ⬆️
unit 80.29% <100.00%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...rvice/pinot/converters/PinotFunctionConverter.java 94.87% <100.00%> (+0.06%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update cc5cdff...4d451f9. Read the comment docs.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

return function.getArgumentsList().stream().filter(e -> e.hasColumnIdentifier()).findFirst();
}

private String getAvgRateLiteral(Function function) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getAvgRateLiteral -> getLiteralForAvgRate?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getRateIntervalForAvgRate ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

@@ -0,0 +1,28 @@
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add tests ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@sarthak77 sarthak77 marked this pull request as ready for review November 19, 2021 11:21
@github-actions

This comment has been minimized.

Copy link
Contributor

@kotharironak kotharironak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@@ -96,6 +95,18 @@ private String functionToStringForAvgRate(
columnName, (double) aggregateIntervalInSeconds / rateIntervalInSeconds);
}

private Optional<Expression> getColumnNameForAvgRate(Function function) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we returning an Optional here if the caller is forcefully doing get()?
Optional here makes sense if the caller needs to deal with the value being present or not.

Copy link
Contributor

@aaron-steinfeld aaron-steinfeld Nov 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Also, this isn't returning a column name, it's returning an expression. If I sent my args out of order, this would still work which is not what we want - we just want backwards compatibility. I would just change the old line 84 to default if empty, and leave the rest as is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

@@ -80,9 +80,8 @@ private String functionToStringForAvgRate(
java.util.function.Function<Expression, String> argumentConverter,
ExecutionContext executionContext) {

String columnName = argumentConverter.apply(function.getArgumentsList().get(0));
String rateIntervalInIso =
function.getArgumentsList().get(1).getLiteral().getValue().getString();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is, change this to something equivalent to

  function.getArgumentsList().size() == 2 
    ? function.getArgumentsList().get(1).getLiteral().getValue().getString() : DEFAULT_AVG_RATE_SIZE;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made the change

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

return function.getArgumentsList().stream().filter(e -> e.hasColumnIdentifier()).findFirst();
}

private String getRateIntervalForAvgRate(Function function) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have integration-tests in query-service. We should definitely add one for this case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have two integration tests for testing the average rate changes. Should I add for this specific case also where average rate is in order-by expression ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We should definitely add one.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

@github-actions

This comment has been minimized.

@@ -1120,14 +1242,19 @@ private QueryRequest buildSimpleQueryWithFilter(Filter filter) {
return builder.build();
}

private void assertPQLQuery(QueryRequest queryRequest, String expectedQuery) {
private void assertPQLQuery(
QueryRequest queryRequest, String expectedQuery, ViewDefinition viewDefinition) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we're going to require passing this in (which is fine), we shouldn't make it a global static.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was because we need service view definition for testing avgrate changes. Rest all use this same view definition.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

private void assertPQLQuery(
QueryRequest queryRequest, String expectedQuery, ViewDefinition viewDefinition) {

when(mockingExecutionContext.getTenantId()).thenReturn("__default");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An assertion shouldn't do mocking of its own. I would guess these are not used by most test cases, which means mockito would be erroring out unless we're running in lenient mode (I'm guessing we are). We don't need to switch lenient off as part of this change, but we should be strict for any new tests we write.

https://javadoc.io/static/org.mockito/mockito-core/3.2.4/org/mockito/quality/Strictness.html#STRICT_STUBS

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getTenantId() is used by most of the tests.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved others to the respective test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we shouldn't share the state though - that's the same problem you ran into with view definition. Have each test pass in their own execution context, same as view def, then they can mock that locally, according to their test parameters. For backwards compat, you could overload the assert method with the existing behavior if you want - that way no existing tests hve to be modified. In the current for, we have a mix of both things we don't want - shared state (including newly introduced shared state) and modifying the existing tests.

}

@Test
public void testQueryWithAverageRateInOrderBy() {
Copy link
Member Author

@sarthak77 sarthak77 Nov 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aaron-steinfeld @avinashkolluru the integration test would be exactly the same as this. Should I keep this test also or remove this one?

Copy link
Contributor

@kotharironak kotharironak Nov 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep this as well. It is checking the expected PQL query. The integration test will be checking the output of the API.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Copy link
Contributor

@aaron-steinfeld aaron-steinfeld left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approving to unblock the bug fix, but we should get the newly added tests cleaned up here or in a followup.

Mockito.when(connection.prepareStatement(any(Request.class))).thenCallRealMethod();
mockingExecutionContext = mock(ExecutionContext.class);
when(mockingExecutionContext.getTenantId()).thenReturn("__default");
when(this.mockingExecutionContext.getTimeSeriesPeriod()).thenReturn(Optional.empty());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this mock is not relevant to every test and would fail in strict mode. please move it such that we only mock things that are relevant to the test.

For future tests (beyond the scope of this PR), make sure to always run in strict mode. The easiest way to do that is probably use the junit extension -

@ExtendWith(MockitoExtension.class)

@sarthak77 sarthak77 merged commit 7df2959 into main Nov 22, 2021
@sarthak77 sarthak77 deleted the fix-order-by-expression branch November 22, 2021 03:16
@github-actions
Copy link

Unit Test Results

  22 files  ±0    22 suites  ±0   8s ⏱️ -1s
126 tests +2  126 ✔️ +2  0 💤 ±0  0 ❌ ±0 

Results for commit 7df2959. ± Comparison against base commit cc5cdff.

@sarthak77
Copy link
Member Author

Raised a follow-up PR for fixing the unit tests : #103

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants