package org.apache.lucene.util;

/*
 * 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.
 */

import org.apache.lucene.util.junitcompat.WithNestedTests;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;

import com.carrotsearch.randomizedtesting.SysGlobals;
import com.carrotsearch.randomizedtesting.annotations.Repeat;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesInvariantRule;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;

/**
 * @see TestRuleIgnoreAfterMaxFailures
 * @see SystemPropertiesInvariantRule
 */
public class TestMaxFailuresRule extends WithNestedTests {
  @Rule
  public SystemPropertiesRestoreRule restoreSysProps = new SystemPropertiesRestoreRule();

  public TestMaxFailuresRule() {
    super(true);
  }

  public static class Nested extends WithNestedTests.AbstractNestedTest {
    @Repeat(iterations = 100)
    public void testFailSometimes() {
      assertFalse(random().nextInt(5) == 0);
    }
  }

  @Test
  public void testMaxFailures() {
    int maxFailures = LuceneTestCase.ignoreAfterMaxFailures.maxFailures;
    int failuresSoFar = LuceneTestCase.ignoreAfterMaxFailures.failuresSoFar;
    System.clearProperty(SysGlobals.SYSPROP_ITERATIONS());
    try {
      LuceneTestCase.ignoreAfterMaxFailures.maxFailures = 2;
      LuceneTestCase.ignoreAfterMaxFailures.failuresSoFar = 0;

      JUnitCore core = new JUnitCore();
      final int [] assumptions = new int [1];
      core.addListener(new RunListener() {
        @Override
        public void testAssumptionFailure(Failure failure) {
          assumptions[0]++; 
        }
      });

      Result result = core.run(Nested.class);
      Assert.assertEquals(100, result.getRunCount());
      Assert.assertEquals(0, result.getIgnoreCount());
      Assert.assertEquals(2, result.getFailureCount());

      // JUnit doesn't pass back the number of successful tests, just make sure
      // we did have enough assumption-failures.
      Assert.assertTrue(assumptions[0] > 50);
    } finally {
      LuceneTestCase.ignoreAfterMaxFailures.maxFailures = maxFailures;
      LuceneTestCase.ignoreAfterMaxFailures.failuresSoFar = failuresSoFar;
    }
  }
}

@@ -917,33 +917,8 @@
 rt;%0A
-import org.junit.Ignore;%0A
 impo
@@ -959,16 +959,53 @@
 t.Test;%0A
+import org.junit.runner.Description;%0A
 import o
@@ -1830,17 +1830,17 @@
 tions = 
-1
+5
 00)%0A    
@@ -2371,40 +2371,51 @@
 nal 
-int %5B%5D assumptions = new int %5B1%5D
+StringBuilder results = new StringBuilder()
 ;%0A  
@@ -2467,107 +2467,570 @@
     
-@Override%0A        public void testAssumptionFailure(Failure failure) %7B%0A          assumptions%5B0%5D++; 
+char lastTest;%0A%0A        @Override%0A        public void testStarted(Description description) throws Exception %7B%0A          lastTest = 'S'; // success.%0A        %7D%0A%0A        @Override%0A        public void testAssumptionFailure(Failure failure) %7B%0A          lastTest = 'A'; // assumption failure.%0A        %7D%0A%0A        @Override%0A        public void testFailure(Failure failure) throws Exception %7B%0A          lastTest = 'F'; // failure%0A        %7D%0A%0A        @Override%0A        public void testFinished(Description description) throws Exception %7B%0A          results.append(lastTest);
 %0A   
@@ -3123,9 +3123,9 @@
 als(
-1
+5
 00, 
@@ -3272,78 +3272,77 @@
  // 
-JUnit doesn't pass back the number of successful tests, just make s
+Make sure we had exactly two failures followed by assumption-fail
 ure
+s
 %0A   
@@ -3351,91 +3351,133 @@
  // 
-we did have enough assumption-failures.%0A      Assert.assertTrue(assumptions%5B0%5D %3E 50
+resulting from ignored tests.%0A      Assert.assertTrue(results.toString(), %0A          results.toString().matches(%22(S*F)%7B2%7DA+%22)
 );%0A 

Correcting the test for the pessimistic random seed.