You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ho...@apache.org on 2016/06/03 18:36:06 UTC
lucene-solr:branch_6x: SOLR-9107: new @RandomizeSSL annotation for
more fine grained control of SSL testing
Repository: lucene-solr
Updated Branches:
refs/heads/branch_6x 9f299bb6a -> 8481d6f47
SOLR-9107: new @RandomizeSSL annotation for more fine grained control of SSL testing
(cherry picked from commit 09372acb660d21b6da01f6ea65f00493126ee32b)
Conflicts:
solr/CHANGES.txt
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/8481d6f4
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/8481d6f4
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/8481d6f4
Branch: refs/heads/branch_6x
Commit: 8481d6f47fdcbbae049d07aa810c9632f44c201b
Parents: 9f299bb
Author: Chris Hostetter <ho...@apache.org>
Authored: Wed Jun 1 14:34:31 2016 -0700
Committer: Chris Hostetter <ho...@apache.org>
Committed: Fri Jun 3 11:12:42 2016 -0700
----------------------------------------------------------------------
solr/CHANGES.txt | 2 +
.../apache/solr/cloud/TestSSLRandomization.java | 202 +++++++++++++++++++
.../java/org/apache/solr/SolrTestCaseJ4.java | 27 ++-
.../java/org/apache/solr/util/RandomizeSSL.java | 174 ++++++++++++++++
4 files changed, 390 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8481d6f4/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index d96ecd9..18b98a0 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -321,6 +321,8 @@ Other Changes
* SOLR-9136: Separate out the error statistics into server-side error vs client-side error
(Jessica Cheng Mallet via Erick Erickson)
+* SOLR-9107: new @RandomizeSSL annotation for more fine grained control of SSL testing (hossman, sarowe)
+
* SOLR-9081: Make SolrTestCaseJ4.beforeClass() / .afterClass() public so it
works with Mockito (Georg Sorst, Alan Woodward)
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8481d6f4/solr/core/src/test/org/apache/solr/cloud/TestSSLRandomization.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestSSLRandomization.java b/solr/core/src/test/org/apache/solr/cloud/TestSSLRandomization.java
index e6dd90e..0c20a49 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestSSLRandomization.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestSSLRandomization.java
@@ -17,9 +17,13 @@
package org.apache.solr.cloud;
import java.lang.invoke.MethodHandles;
+import java.util.Arrays;
import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.SolrTestCaseJ4.SuppressSSL;
import org.apache.solr.util.SSLTestConfig;
+import org.apache.solr.util.RandomizeSSL;
+import org.apache.solr.util.RandomizeSSL.SSLRandomizer;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@@ -34,6 +38,7 @@ import org.slf4j.LoggerFactory;
*
* @see TestMiniSolrCloudClusterSSL
*/
+@RandomizeSSL(ssl=0.5,reason="frequent SSL usage to make test worth while")
public class TestSSLRandomization extends SolrCloudTestCase {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -51,4 +56,201 @@ public class TestSSLRandomization extends SolrCloudTestCase {
String url = buildUrl(6666, "/foo");
assertEquals(sslConfig.isSSLMode() ? "https://127.0.0.1:6666/foo" : "http://127.0.0.1:6666/foo", url);
}
+
+ /** Used by {@link #testSSLRandomizer} */
+ @RandomizeSSL(ssl=0.42,clientAuth=0.33,reason="foo")
+ public class FullyAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ public class InheritedFullyAnnotated extends FullyAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ public class NotAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ public class InheritedNotAnnotated extends NotAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ @SuppressSSL(bugUrl="fakeBugUrl")
+ public class Suppressed { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ public class InheritedSuppressed extends Suppressed { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ @SuppressSSL(bugUrl="fakeBugUrl")
+ public class InheritedAnnotationButSuppressed extends FullyAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ @RandomizeSSL(ssl=0.42,clientAuth=0.33,reason="foo")
+ public class InheritedSuppressedWithIgnoredAnnotation extends Suppressed {
+ // Even with direct annotation, supression at superclass overrules us.
+ //
+ // (If it didn't work this way, it would be a pain in the ass to quickly disable SSL for a
+ // broad hierarchy of tests)
+ };
+
+ /** Used by {@link #testSSLRandomizer} */
+ @RandomizeSSL()
+ public class EmptyAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ public class InheritedEmptyAnnotated extends EmptyAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ @RandomizeSSL(0.5)
+ public class InheritedEmptyAnnotatationWithOverride extends EmptyAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ @RandomizeSSL(ssl=0.42,clientAuth=0.33,reason="foo")
+ public class GrandchildInheritedEmptyAnnotatationWithOverride extends InheritedEmptyAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ @RandomizeSSL(0.5)
+ public class SimplyAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ @RandomizeSSL(0.0)
+ public class MinAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ @RandomizeSSL(1)
+ public class MaxAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ @RandomizeSSL(ssl=0.42)
+ public class SSlButNoClientAuthAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ @RandomizeSSL(clientAuth=0.42)
+ public class ClientAuthButNoSSLAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ @RandomizeSSL(ssl=42.0)
+ public class SSLOutOfRangeAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ @RandomizeSSL(clientAuth=42.0)
+ public class ClientAuthOutOfRangeAnnotated { };
+
+ /** Used by {@link #testSSLRandomizer} */
+ public class InheritedOutOfRangeAnnotated extends ClientAuthOutOfRangeAnnotated { };
+
+ public void testSSLRandomizer() {
+ SSLRandomizer r;
+ // for some cases, we know exactly what the config should be regardless of randomization factors
+ SSLTestConfig conf;
+
+ for (Class c : Arrays.asList(FullyAnnotated.class, InheritedFullyAnnotated.class,
+ GrandchildInheritedEmptyAnnotatationWithOverride.class )) {
+ r = SSLRandomizer.getSSLRandomizerForClass(c);
+ assertEquals(c.toString(), 0.42D, r.ssl, 0.0D);
+ assertEquals(c.toString(), 0.33D, r.clientAuth, 0.0D);
+ assertTrue(c.toString(), r.debug.contains("foo"));
+ }
+
+ for (Class c : Arrays.asList(NotAnnotated.class, InheritedNotAnnotated.class)) {
+ r = SSLRandomizer.getSSLRandomizerForClass(c);
+ assertEquals(c.toString(), 0.0D, r.ssl, 0.0D);
+ assertEquals(c.toString(), 0.0D, r.clientAuth, 0.0D);
+ assertTrue(c.toString(), r.debug.contains("not specified"));
+ conf = r.createSSLTestConfig();
+ assertEquals(c.toString(), false, conf.isSSLMode());
+ assertEquals(c.toString(), false, conf.isClientAuthMode());
+ }
+
+ for (Class c : Arrays.asList(Suppressed.class,
+ InheritedSuppressed.class,
+ InheritedAnnotationButSuppressed.class,
+ InheritedSuppressedWithIgnoredAnnotation.class)) {
+ r = SSLRandomizer.getSSLRandomizerForClass(Suppressed.class);
+ assertEquals(c.toString(), 0.0D, r.ssl, 0.0D);
+ assertEquals(c.toString(), 0.0D, r.clientAuth, 0.0D);
+ assertTrue(c.toString(), r.debug.contains("SuppressSSL"));
+ assertTrue(c.toString(), r.debug.contains("fakeBugUrl"));
+ conf = r.createSSLTestConfig();
+ assertEquals(c.toString(), false, conf.isSSLMode());
+ assertEquals(c.toString(), false, conf.isClientAuthMode());
+ }
+
+ for (Class c : Arrays.asList(EmptyAnnotated.class, InheritedEmptyAnnotated.class)) {
+ r = SSLRandomizer.getSSLRandomizerForClass(c);
+ assertEquals(c.toString(), RandomizeSSL.DEFAULT_ODDS, r.ssl, 0.0D);
+ assertEquals(c.toString(), RandomizeSSL.DEFAULT_ODDS, r.clientAuth, 0.0D);
+ }
+
+ for (Class c : Arrays.asList(SimplyAnnotated.class, InheritedEmptyAnnotatationWithOverride.class)) {
+ r = SSLRandomizer.getSSLRandomizerForClass(c);
+ assertEquals(c.toString(), 0.5D, r.ssl, 0.0D);
+ assertEquals(c.toString(), 0.5D, r.clientAuth, 0.0D);
+ }
+
+ r = SSLRandomizer.getSSLRandomizerForClass(MinAnnotated.class);
+ assertEquals(0.0D, r.ssl, 0.0D);
+ assertEquals(0.0D, r.clientAuth, 0.0D);
+ conf = r.createSSLTestConfig();
+ assertEquals(false, conf.isSSLMode());
+ assertEquals(false, conf.isClientAuthMode());
+
+ r = SSLRandomizer.getSSLRandomizerForClass(MaxAnnotated.class);
+ assertEquals(1.0D, r.ssl, 0.0D);
+ assertEquals(1.0D, r.clientAuth, 0.0D);
+ conf = r.createSSLTestConfig();
+ assertEquals(true, conf.isSSLMode());
+ assertEquals(true, conf.isClientAuthMode());
+
+ r = SSLRandomizer.getSSLRandomizerForClass(SSlButNoClientAuthAnnotated.class);
+ assertEquals(0.42D, r.ssl, 0.0D);
+ assertEquals(0.42D, r.clientAuth, 0.0D);
+
+ r = SSLRandomizer.getSSLRandomizerForClass(ClientAuthButNoSSLAnnotated.class);
+ assertEquals(RandomizeSSL.DEFAULT_ODDS, r.ssl, 0.0D);
+ assertEquals(0.42D, r.clientAuth, 0.0D);
+
+ for (Class c : Arrays.asList(SSLOutOfRangeAnnotated.class,
+ ClientAuthOutOfRangeAnnotated.class,
+ InheritedOutOfRangeAnnotated.class)) {
+ expectThrows(IllegalArgumentException.class, () -> {
+ Object trash = SSLRandomizer.getSSLRandomizerForClass(c);
+ });
+ }
+
+ }
+ public void testSSLRandomizerEffectiveOdds() {
+ assertEquals(RandomizeSSL.DEFAULT_ODDS,
+ SSLRandomizer.getEffectiveOdds(RandomizeSSL.DEFAULT_ODDS, false, 1), 0.0005D);
+ assertEquals(0.2727D,
+ SSLRandomizer.getEffectiveOdds(RandomizeSSL.DEFAULT_ODDS, true, 1), 0.0005D);
+
+ assertEquals(0.0100D, SSLRandomizer.getEffectiveOdds(0.01D, false, 1), 0.0005D);
+ assertEquals(0.1000D, SSLRandomizer.getEffectiveOdds(0.01D, true, 1), 0.0005D);
+ assertEquals(0.6206D, SSLRandomizer.getEffectiveOdds(0.01D, false, 5), 0.0005D);
+
+ assertEquals(0.5000D, SSLRandomizer.getEffectiveOdds(0.5D, false, 1), 0.0005D);
+ assertEquals(0.5454D, SSLRandomizer.getEffectiveOdds(0.5D, true, 1), 0.0005D);
+ assertEquals(0.8083D, SSLRandomizer.getEffectiveOdds(0.5D, false, 5), 0.0005D);
+
+ assertEquals(0.8000D, SSLRandomizer.getEffectiveOdds(0.8D, false, 1), 0.0005D);
+ assertEquals(0.8181D, SSLRandomizer.getEffectiveOdds(0.8D, true, 1), 0.0005D);
+ assertEquals(0.9233D, SSLRandomizer.getEffectiveOdds(0.8D, false, 5), 0.0005D);
+
+ // never ever
+ assertEquals(0.0D, SSLRandomizer.getEffectiveOdds(0.0D, false, 1), 0.0D);
+ assertEquals(0.0D, SSLRandomizer.getEffectiveOdds(0.0D, true, 100), 0.0D);
+ assertEquals(0.0D, SSLRandomizer.getEffectiveOdds(0.0D, false, 100), 0.0D);
+ assertEquals(0.0D, SSLRandomizer.getEffectiveOdds(0.0D, true, 10000), 0.0D);
+ assertEquals(0.0D, SSLRandomizer.getEffectiveOdds(0.0D, false, 10000), 0.0D);
+ assertEquals(0.0D, SSLRandomizer.getEffectiveOdds(0.0D, random().nextBoolean(), random().nextInt()), 0.0D);
+
+ // always
+ assertEquals(1.0D, SSLRandomizer.getEffectiveOdds(1.0D, false, 1), 0.0D);
+ assertEquals(1.0D, SSLRandomizer.getEffectiveOdds(1.0D, true, 100), 0.0D);
+ assertEquals(1.0D, SSLRandomizer.getEffectiveOdds(1.0D, false, 100), 0.0D);
+ assertEquals(1.0D, SSLRandomizer.getEffectiveOdds(1.0D, true, 10000), 0.0D);
+ assertEquals(1.0D, SSLRandomizer.getEffectiveOdds(1.0D, false, 10000), 0.0D);
+ assertEquals(1.0D, SSLRandomizer.getEffectiveOdds(1.0D, random().nextBoolean(), random().nextInt()), 0.0D);
+
+ }
+
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8481d6f4/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
index 2974a86..c1e9954 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
@@ -105,6 +105,8 @@ import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.servlet.DirectSolrConnection;
import org.apache.solr.util.AbstractSolrTestCase;
+import org.apache.solr.util.RandomizeSSL;
+import org.apache.solr.util.RandomizeSSL.SSLRandomizer;
import org.apache.solr.util.RefCounted;
import org.apache.solr.util.RevertDefaultThreadHandlerRule;
import org.apache.solr.util.SSLTestConfig;
@@ -138,6 +140,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
})
@SuppressSysoutChecks(bugUrl = "Solr dumps tons of logs to console.")
@SuppressFileSystems("ExtrasFS") // might be ok, the failures with e.g. nightly runs might be "normal"
+@RandomizeSSL()
public abstract class SolrTestCaseJ4 extends LuceneTestCase {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -316,27 +319,21 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
}
private static SSLTestConfig buildSSLConfig() {
- // test has been disabled
- if (RandomizedContext.current().getTargetClass().isAnnotationPresent(SuppressSSL.class)) {
- return new SSLTestConfig();
- }
+
+ SSLRandomizer sslRandomizer =
+ SSLRandomizer.getSSLRandomizerForClass(RandomizedContext.current().getTargetClass());
- // we don't choose ssl that often because of SOLR-5776
- final boolean trySsl = random().nextInt(10) < 2;
- // NOTE: clientAuth is useless unless trySsl==true, but we randomize it independently
- // just in case it might find bugs in our test/ssl client code (ie: attempting to use
- // SSL w/client cert to non-ssl servers)
- boolean trySslClientAuth = random().nextInt(10) < 2;
if (Constants.MAC_OS_X) {
// see SOLR-9039
// If a solution is found to remove this, please make sure to also update
// TestMiniSolrCloudClusterSSL.testSslAndClientAuth as well.
- trySslClientAuth = false;
+ sslRandomizer = new SSLRandomizer(sslRandomizer.ssl, 0.0D, (sslRandomizer.debug + " w/ MAC_OS_X supressed clientAuth"));
}
-
- log.info("Randomized ssl ({}) and clientAuth ({})", trySsl, trySslClientAuth);
-
- return new SSLTestConfig(trySsl, trySslClientAuth);
+
+ SSLTestConfig result = sslRandomizer.createSSLTestConfig();
+ log.info("Randomized ssl ({}) and clientAuth ({}) via: {}",
+ result.isSSLMode(), result.isClientAuthMode(), sslRandomizer.debug);
+ return result;
}
protected static JettyConfig buildJettyConfig(String context) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8481d6f4/solr/test-framework/src/java/org/apache/solr/util/RandomizeSSL.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/util/RandomizeSSL.java b/solr/test-framework/src/java/org/apache/solr/util/RandomizeSSL.java
new file mode 100644
index 0000000..e7336d8
--- /dev/null
+++ b/solr/test-framework/src/java/org/apache/solr/util/RandomizeSSL.java
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+package org.apache.solr.util;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.TestUtil;
+import org.apache.solr.SolrTestCaseJ4.SuppressSSL;
+
+
+/**
+ * Marker annotation indicating when SSL Randomization should be used for a test class, and if so what
+ * the typical odds of using SSL should for that test class.
+ * @see SSLRandomizer#getSSLRandomizerForClass
+ * @see SuppressSSL
+ */
+@Documented
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface RandomizeSSL {
+
+ // we don't choose ssl that often by default because of SOLR-5776
+ public static final double DEFAULT_ODDS = 0.2D;
+ /** Comment to inlcude when logging details of SSL randomization */
+ public String reason() default "";
+ /**
+ * Odds (as ratio relative to 1) that SSL should be selected in a typical run.
+ * Must either be betwen 0.0 and 1.0 (inclusively) or NaN in which case a sensible should be used.
+ * Actual Odds used for randomization may be higher depending on runner options such as
+ * <code>tests.multiplier</code> or <code>tests.nightly</code>
+ *
+ * @see #DEFAULT_ODDS
+ * @see LuceneTestCase#TEST_NIGHTLY
+ * @see LuceneTestCase#RANDOM_MULTIPLIER
+ */
+ public double ssl() default Double.NaN;
+ /**
+ * Odds (as ratio relative to 1) that SSL should be selected in a typical run.
+ * Must either be betwen 0.0 and 1.0 (inclusively) or NaN in which case the effective value of
+ * {@link #ssl} should be used.
+ * Actual Odds used for randomization may be higher depending on runner options such as
+ * <code>tests.multiplier</code> or <code>tests.nightly</code>
+ * <p>
+ * NOTE: clientAuth is useless unless ssl is also in used, but we randomize it independently
+ * just in case it might find bugs in our test/ssl client code (ie: attempting to use
+ * SSL w/client cert to non-ssl servers)
+ * </p>
+ * @see #DEFAULT_ODDS
+ * @see LuceneTestCase#TEST_NIGHTLY
+ * @see LuceneTestCase#RANDOM_MULTIPLIER
+ */
+ public double clientAuth() default Double.NaN;
+ /**
+ * A shorthand option for controlling both {@link #ssl} and {@link #clientAuth} with a single numeric
+ * value, For example: <code>@RandomizeSSL(0.5)</code>.
+ *
+ * Ignored if {@link #ssl} is set explicitly.
+ */
+ public double value() default Double.NaN;
+
+ /**
+ * A simple data structure for encapsulating the effective values to be used when randomizing
+ * SSL in a test, based on the configured values in the {@link RandomizeSSL} annotation.
+ */
+ public static final class SSLRandomizer {
+ public final double ssl;
+ public final double clientAuth;
+ public final String debug;
+ /** @lucene.internal */
+ public SSLRandomizer(double ssl, double clientAuth, String debug) {
+ this.ssl = ssl;
+ this.clientAuth = clientAuth;
+ this.debug = debug;
+ }
+
+ /**
+ * Randomly produces an SSLTestConfig taking into account various factors
+ *
+ * @see LuceneTestCase#TEST_NIGHTLY
+ * @see LuceneTestCase#RANDOM_MULTIPLIER
+ * @see LuceneTestCase#random()
+ */
+ public SSLTestConfig createSSLTestConfig() {
+ // even if we know SSL is disabled, always consume the same amount of randomness
+ // that way all other test behavior should be consistent even if a user adds/removes @SuppressSSL
+
+ final boolean useSSL = TestUtil.nextInt(LuceneTestCase.random(), 0, 1000) <
+ (int)(1000 * getEffectiveOdds(ssl, LuceneTestCase.TEST_NIGHTLY, LuceneTestCase.RANDOM_MULTIPLIER));
+ final boolean useClientAuth = TestUtil.nextInt(LuceneTestCase.random(), 0, 1000) <
+ (int)(1000 * getEffectiveOdds(clientAuth, LuceneTestCase.TEST_NIGHTLY, LuceneTestCase.RANDOM_MULTIPLIER));
+
+ return new SSLTestConfig(useSSL, useClientAuth);
+ }
+
+ /** @lucene.internal Public only for testing */
+ public static double getEffectiveOdds(final double declaredOdds,
+ final boolean nightly,
+ final int multiplier) {
+ assert declaredOdds <= 1.0D;
+ assert 0.0D <= declaredOdds;
+
+ if (declaredOdds == 0.0D || declaredOdds == 1.0D ) {
+ return declaredOdds;
+ }
+
+ assert 0 < multiplier;
+
+ // negate the odds so we can then divide it by our multipling factors
+ // to increase the final odds
+ return 1.0D - ((1.0D - declaredOdds)
+ / ((nightly ? 1.1D : 1.0D) * (1.0D + Math.log(multiplier))));
+ }
+
+ /**
+ * Returns an SSLRandomizer suitable for the specified (test) class
+ */
+ public static final SSLRandomizer getSSLRandomizerForClass(Class clazz) {
+
+ final SuppressSSL suppression = (SuppressSSL) clazz.getAnnotation(SuppressSSL.class);
+ if (null != suppression) {
+ // Even if this class has a RandomizeSSL annotation, any usage of SuppressSSL -- even in a
+ // super class -- overrules that.
+ //
+ // (If it didn't work this way, it would be a pain in the ass to quickly disable SSL for a
+ // broad hierarchy of tests)
+ return new SSLRandomizer(0.0D, 0.0D, suppression.toString());
+ }
+
+ final RandomizeSSL annotation = (RandomizeSSL) clazz.getAnnotation(RandomizeSSL.class);
+
+ if (null == annotation) {
+ return new SSLRandomizer(0.0D, 0.0D, RandomizeSSL.class.getName() + " annotation not specified");
+ }
+
+ final double def = Double.isNaN(annotation.value()) ? DEFAULT_ODDS : annotation.value();
+ if (def < 0.0D || 1.0D < def) {
+ throw new IllegalArgumentException
+ (clazz.getName() + ": default value is not a ratio between 0 and 1: " + annotation.toString());
+ }
+ final double ssl = Double.isNaN(annotation.ssl()) ? def : annotation.ssl();
+ if (ssl < 0.0D || 1.0D < ssl) {
+ throw new IllegalArgumentException
+ (clazz.getName() + ": ssl value is not a ratio between 0 and 1: " + annotation.toString());
+ }
+ final double clientAuth = Double.isNaN(annotation.clientAuth()) ? ssl : annotation.clientAuth();
+ if (clientAuth < 0.0D || 1 < clientAuth) {
+ throw new IllegalArgumentException
+ (clazz.getName() + ": clientAuth value is not a ratio between 0 and 1: " + annotation.toString());
+ }
+ return new SSLRandomizer(ssl, clientAuth, annotation.toString());
+ }
+ }
+}