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

Make authentication request parameter order to be deterministic #8185

Merged

Conversation

rRajivramachandran
Copy link
Contributor

Description

This PR is to fix a few tests whose results are non deterministic/flaky in the module plugins/network-elements/nicira-nvp.

Setup:

Java version: 11.0.20.1
Maven version: 3.8.8

Test failure reproduction:

The test com.cloud.network.nicira.NiciraRestClientTest#testExecuteLiveLockWhenControllerAllowsLoginAndFollowsWithUnauthorizedButDoesNotRediect assumes the order of keys to be maintained by a HashMap. This issue was verified using the NonDex plugin.

Steps:

git clone https://github.com/apache/cloudstack.git
cd cloudstack
mvn install -pl plugins/network-elements/nicira-nvp -am -DskipTests
mvn -pl plugins/network-elements/nicira-nvp edu.illinois:nondex-maven-plugin:2.1.1:nondex -Dtest=com.cloud.network.nicira.NiciraRestClientTest#testExecuteLiveLockWhenControllerAllowsLoginAndFollowsWithUnauthorizedButDoesNotRediect

Root cause and fix:

Test failure in NonDex mode:

[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.767 s <<< FAILURE! - in com.cloud.network.nicira.NiciraRestClientTest
[ERROR] testExecuteLiveLockWhenControllerAllowsLoginAndFollowsWithUnauthorizedButDoesNotRediect(com.cloud.network.nicira.NiciraRestClientTest)  Time elapsed: 1.761 s  <<< ERROR!
java.lang.NullPointerException

The NullPointerException occurs at the following location

because the mockResponse created in the test, does not get returned for the execute method.

The HttpRequestMatcher serializes the request object to a string

payload = EntityUtils.toString(((HttpEntityEnclosingRequest) request).getEntity());

To verify that the issue was due to the HttpRequestMatcher used by mockito, the following line:

when(httpClient.execute(eq(HTTP_HOST), HttpRequestMatcher.eq(loginRequest), eq(httpClientContext)))

was modfied to read when(httpClient.execute(eq(HTTP_HOST), any(HttpUriRequest.class), eq(httpClientContext))).

This allows matching any request class object. The test passed with this change when run on the NonDex tool confirming that the issue was here.

On adding logs to the HttpRequestMatcher class, it was deduced that the test fails when the order of keys returned by the login parameters is not the same as that configured in the test class.

Failing case(ordered shuffled):

2023-10-19 18:11:15,312 ERROR [root] (main:) Wanted payload:password=adminpassword&username=admin
2023-10-19 18:11:15,312 ERROR [root] (main:) Actual payload:username=admin&password=adminpassword
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.423 s <<< FAILURE! - in com.cloud.network.nicira.NiciraRestClientTest
[ERROR] testExecuteLiveLockWhenControllerAllowsLoginAndFollowsWithUnauthorizedButDoesNotRediect(com.cloud.network.nicira.NiciraRestClientTest)  Time elapsed: 1.413 s  <<< ERROR!
java.lang.NullPointerException

Passing case(order not shuffled):

2023-10-19 18:11:09,513 ERROR [root] (main:) Wanted payload:username=admin&password=adminpassword
2023-10-19 18:11:09,517 ERROR [root] (main:) Actual payload:username=admin&password=adminpassword
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.968 s - in com.cloud.network.nicira.NiciraRestClientTest

The test class configures login parameters here:

public static void setupClass() {
loginParameters.put("username", ADMIN);
loginParameters.put("password", ADMIN_PASSWORD);
request = HttpUriRequestBuilder.create()
.method(HttpMethods.GET)
.path("/path")
.build();
loginRequest = HttpUriRequestBuilder.create()
.method(HttpMethods.POST)
.methodParameters(loginParameters)
.path(LOGIN_PATH)
.build();

and the source code builds them here:

private HttpUriRequest createAuthenticationRequest() {
final Map<String, String> parameters = new HashMap<>();
parameters.put("username", username);
parameters.put("password", password);
return HttpUriRequestBuilder.create()
.method(HttpMethods.POST)
.methodParameters(parameters)
.path(loginUrl)
.build();
}

Fix

To make the map ordered for ensuring deterministic results during serialization/deserialization, changes were done at the source code and test by converting the HashMap to a LinkedHashMap.

Additional fixes

The change also fixed following tests in the same class which were flaky due to the same reason:

  • com.cloud.network.nicira.NiciraRestClientTest#testExecuteTwoConsecutiveUnauthorizedExecutions
  • com.cloud.network.nicira.NiciraRestClientTest#testExecuteUnauthorizedThenSuccess

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • build/CI

Feature/Enhancement Scale or Bug Severity

The fix is backward compatible as it merely changes an unordered map implementation to an ordered one for ensuring that when string serialization of the map is done, results are deterministic.

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

  • The test passes when run with the NonDex tool(mvn -pl plugins/network-elements/nicira-nvp edu.illinois:nondex-maven-plugin:2.1.1:nondex -Dtest=com.cloud.network.nicira.NiciraRestClientTest#testExecuteLiveLockWhenControllerAllowsLoginAndFollowsWithUnauthorizedButDoesNotRediect).
  • The entire test suite of the module passes(mvn -pl plugins/network-elements/nicira-nvp test).

How did you try to break this feature and the system with this change?

The change does not affect any feature as it only makes an unordered data structured as ordered. This does not enforce any constraints on source code and is an internal implementation detail. However it makes the code more deterministic in cases where serialization to strings is done directly, which is the case for some tests

Copy link
Contributor

@DaanHoogland DaanHoogland left a comment

Choose a reason for hiding this comment

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

clgtm, but I think the nicira code needs to be phased out (out of scope for this PR).

@rohityadavcloud
Copy link
Member

Nicira is likely not support, unmaintained - are you a Nicira user @rRajivramachandran - could you advise if there's a reason around the PR?

@rRajivramachandran
Copy link
Contributor Author

rRajivramachandran commented Nov 3, 2023

@rohityadavcloud I am not a user of the tool directly. I am a UIUC(University of Illinois Urbana Champaign) student who is working on improving flaky tests in different open source projects. Would it be possible to merge this contribution

@shwstppr
Copy link
Contributor

shwstppr commented Nov 4, 2023

@blueorangutan package

@blueorangutan
Copy link

@shwstppr a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

Copy link

codecov bot commented Nov 4, 2023

Codecov Report

Merging #8185 (3b6553a) into main (121531e) will decrease coverage by 0.05%.
Report is 2 commits behind head on main.
The diff coverage is 50.00%.

@@             Coverage Diff              @@
##               main    #8185      +/-   ##
============================================
- Coverage     29.19%   29.15%   -0.05%     
+ Complexity    31015    30970      -45     
============================================
  Files          5181     5181              
  Lines        365255   365255              
  Branches      53427    53427              
============================================
- Hits         106646   106491     -155     
- Misses       243988   244153     +165     
+ Partials      14621    14611      -10     
Flag Coverage Δ
simulator-marvin-tests 25.09% <0.00%> (-0.07%) ⬇️
uitests 4.50% <ø> (ø)
unit-tests 14.80% <100.00%> (ø)

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

Files Coverage Δ
...ava/com/cloud/network/nicira/NiciraRestClient.java 82.66% <100.00%> (ø)
...va/com/cloud/utils/rest/HttpUriRequestBuilder.java 0.00% <0.00%> (ø)

... and 33 files with indirect coverage changes

📣 Codecov offers a browser extension for seamless coverage viewing on GitHub. Try it in Chrome or Firefox today!

@shwstppr
Copy link
Contributor

shwstppr commented Nov 6, 2023

@blueorangutan package

@blueorangutan
Copy link

@shwstppr a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@weizhouapache
Copy link
Member

Nicira is likely not support, unmaintained - are you a Nicira user @rRajivramachandran - could you advise if there's a reason around the PR?

we could remove the plugin in the near future

this PR is not useful, but we can merge.

@DaanHoogland
Copy link
Contributor

Nicira is likely not support, unmaintained - are you a Nicira user @rRajivramachandran - could you advise if there's a reason around the PR?

we could remove the plugin in the near future

this PR is not useful, but we can merge.

If it helps @rRajivramachandran , ... I think this is not bothering anyone else

@DaanHoogland DaanHoogland merged commit e9b24b6 into apache:main Nov 6, 2023
24 of 25 checks passed
@blueorangutan
Copy link

Packaging result [SF]: ✔️ el7 ✔️ el8 ✔️ el9 ✔️ debian ✔️ suse15. SL-JID 7643

dhslove pushed a commit to ablecloud-team/ablestack-cloud that referenced this pull request Nov 8, 2023
Dajeong-Park added a commit to Dajeong-Park/ablestack-cloud that referenced this pull request Nov 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants