apache / helix

Mirror of Apache Helix
Apache License 2.0
461 stars 224 forks source link

Fix flaky test TestCustomizedViewAggregation.testCustomizedViewAggregation #1277

Closed kaisun2000 closed 3 years ago

kaisun2000 commented 4 years ago

In github, log:

2020-08-14T23:50:43.0366557Z [ERROR] TestCustomizedViewAggregation.testCustomizedViewAggregation:415->validateAggregationSnapshot:259 expected: but was:

2020-08-14T23:50:42.7830650Z [ERROR] testCustomizedViewAggregation(org.apache.helix.integration.TestCustomizedViewAggregation) Time elapsed: 19.86 s <<< FAILURE! 2020-08-14T23:50:42.7831051Z java.lang.AssertionError: expected: but was: 2020-08-14T23:50:42.7831294Z at org.apache.helix.integration.TestCustomizedViewAggregation.validateAggregationSnapshot(TestCustomizedViewAggregation.java:259) 2020-08-14T23:50:42.7831628Z at org.apache.helix.integration.TestCustomizedViewAggregation.testCustomizedViewAggregation(TestCustomizedViewAggregation.java:415)

kaisun2000 commented 4 years ago
 private void validateAggregationSnapshot() throws Exception {
    boolean result = TestHelper.verify(new TestHelper.Verifier() {
      @Override
      public boolean verify() {
        Map<String, Map<String, RoutingTableSnapshot>> routingTableSnapshots =
            _routingTableProvider.getRoutingTableSnapshots();

        // Get customized view snapshot
        Map<String, RoutingTableSnapshot> fullCustomizedViewSnapshot =
            routingTableSnapshots.get(PropertyType.CUSTOMIZEDVIEW.name());

        if (fullCustomizedViewSnapshot.isEmpty() && !_routingTableProviderDataSources.isEmpty()) {
          return false;
        }

        for (String customizedStateType : fullCustomizedViewSnapshot.keySet()) {
          if (!_routingTableProviderDataSources.contains(customizedStateType)) {
            return false;
          }

          // Get per customized state type snapshot
          RoutingTableSnapshot customizedViewSnapshot =
              fullCustomizedViewSnapshot.get(customizedStateType);

          // local per customized state type map
          Map<String, Map<String, Map<String, String>>> localSnapshot =
              _localCustomizedView.getOrDefault(customizedStateType, Maps.newHashMap());

          Collection<CustomizedView> customizedViews = customizedViewSnapshot.getCustomizeViews();

          // If a customized state is not set to be aggregated in config, but is enabled in routing table provider, it will show up in customized view returned to user, but will be empty
          if (!_aggregationEnabledTypes.contains(customizedStateType)
              && customizedViews.size() != 0) {
            return false;
          }

          if (_aggregationEnabledTypes.contains(customizedStateType)
              && customizedViews.size() != localSnapshot.size()) {
            return false;
          }

          // Get per resource snapshot
          for (CustomizedView resourceCustomizedView : customizedViews) {
            ZNRecord record = resourceCustomizedView.getRecord();
            Map<String, Map<String, String>> resourceStateMap = record.getMapFields();

            // Get local per resource map
            Map<String, Map<String, String>> localPerResourceCustomizedView = localSnapshot
                .getOrDefault(resourceCustomizedView.getResourceName(), Maps.newHashMap());

            if (resourceStateMap.size() != localPerResourceCustomizedView.size()) {
              return false;
            }

            // Get per partition snapshot
            for (String partitionName : resourceStateMap.keySet()) {
              Map<String, String> stateMap =
                  resourceStateMap.getOrDefault(partitionName, Maps.newTreeMap());

              // Get local per partition map
              Map<String, String> localStateMap =
                  localPerResourceCustomizedView.getOrDefault(partitionName, Maps.newTreeMap());

              if (stateMap.isEmpty() && !localStateMap.isEmpty()) {
                return false;
              }

              for (String instanceName : stateMap.keySet()) {
                // Per instance value
                String stateMapValue = stateMap.get(instanceName);
                String localStateMapValue = localStateMap.get(instanceName);
                if (!stateMapValue.equals(localStateMapValue)) {
                  return false;
                }
              }
            }
          }
        }
        return true;
      }
    }, TestHelper.WAIT_DURATION);

    Assert.assertTrue(result);  -------> failed here, TestHelper.WAIT_DURATION is 20s by default.

More likely than not, the issue is 20s is not long enough.

Action is to ad log and enable longer WAIT_DURATION.

jiajunwang commented 3 years ago

Close test unstable tickets since we have an automatic tracking mechanism https://github.com/apache/helix/pull/1757 now for tracking the most recent test issues.