/** Tests that different profiles can have different values for pvalue. */
  public void testDifferentProfiles() throws Exception {
    MockedCertificateSamplerCustomPublisher publisher;
    Properties config;

    // Default: p=1.0, A: p=0.0, B: p=1.0
    config = new Properties();
    config.setProperty("outputfolder", TEMP_DIR.getAbsolutePath());
    config.setProperty("default.samplingmethod", "SAMPLE_PROBABILISTIC");
    config.setProperty("default.pvalue", "1.0");
    config.setProperty("profileid." + PROFILE_A + ".pvalue", "0.0");
    config.setProperty("profileid." + PROFILE_B + ".pvalue", "1.0");

    publisher = createMockedPublisher(config);
    assertTrue(storeCertificate(publisher, SecConst.CERT_ACTIVE, PROFILE_A));
    assertFalse(
        "Certificate in profile A should not be stored", publisher.isWriteCertificateCalled());

    publisher = createMockedPublisher(config);
    assertTrue(storeCertificate(publisher, SecConst.CERT_ACTIVE, PROFILE_B));
    assertTrue(
        "Certificate in profile B should have been stored", publisher.isWriteCertificateCalled());

    publisher = createMockedPublisher(config);
    assertTrue(storeCertificate(publisher, SecConst.CERT_ACTIVE, ANY_PROFILEID));
    assertTrue(
        "Certificate in any other profile should have been stored",
        publisher.isWriteCertificateCalled());
  }
  /** Tests the NONE sample method. */
  public void testSampleNone() throws Exception {
    MockedCertificateSamplerCustomPublisher publisher;
    Properties config;

    // Default: NONE
    // Nothing should be stored
    config = new Properties();
    config.setProperty("outputfolder", TEMP_DIR.getAbsolutePath());
    config.setProperty("default.samplingmethod", "SAMPLE_NONE");

    publisher = createMockedPublisher(config);
    assertTrue(storeCertificate(publisher, SecConst.CERT_ACTIVE, ANY_PROFILEID));
    assertFalse(
        "Certificate in no profile should not be stored", publisher.isWriteCertificateCalled());

    // Default: ALL, A: NONE
    // Only from profile A should be stored
    config = new Properties();
    config.setProperty("outputfolder", TEMP_DIR.getAbsolutePath());
    config.setProperty("default.samplingmethod", "SAMPLE_ALL");
    config.setProperty("profileid." + PROFILE_A + ".samplingmethod", "SAMPLE_NONE");

    publisher = createMockedPublisher(config);
    assertTrue(storeCertificate(publisher, SecConst.CERT_ACTIVE, PROFILE_A));
    assertFalse(
        "Certificate in profile A should not be stored", publisher.isWriteCertificateCalled());
    publisher = createMockedPublisher(config);
    assertTrue(storeCertificate(publisher, SecConst.CERT_ACTIVE, ANY_PROFILEID));
    assertTrue(
        "Certificate in other profile should be stored", publisher.isWriteCertificateCalled());
  }
  /** Tests that testConnection gives error if pvalue is invalid. */
  public void testPvalueNotInInterval() throws Exception {
    MockedCertificateSamplerCustomPublisher publisher;
    Properties config;

    // Profile pvalue=-0.5 (illegal)
    config = new Properties();
    config.setProperty("outputfolder", TEMP_DIR.getAbsolutePath());
    config.setProperty("default.samplingmethod", "SAMPLE_ALL");
    config.setProperty("profileid." + PROFILE_A + ".samplingmethod", "SAMPLE_PROBABILISTIC");
    config.setProperty("profileid." + PROFILE_A + ".pvalue", "-0.5");

    publisher = createMockedPublisher(config);
    try {
      publisher.testConnection(ANY_ADMIN);
      fail("Should have failed as pvalue is not in the [0, 1] range");
    } catch (PublisherConnectionException expected) {
    } // NOPMD

    // Default pvalue=-0.5 (illegal)
    config = new Properties();
    config.setProperty("outputfolder", TEMP_DIR.getAbsolutePath());
    config.setProperty("default.samplingmethod", "SAMPLE_PROBABILISTIC");
    config.setProperty("default.pvalue", "-0.5");

    publisher = createMockedPublisher(config);
    try {
      publisher.testConnection(ANY_ADMIN);
      fail("Should have failed as pvalue is not in the [0, 1] range");
    } catch (PublisherConnectionException expected) {
    } // NOPMD
  }
  /** Tests that publishing with sampling method ALL stores the certificate. */
  public void testSampleAll() throws Exception {
    MockedCertificateSamplerCustomPublisher publisher;
    boolean success;

    publisher = createMockedPublisher(CONFIG_SAMPLE_ALL);
    success = storeCertificate(publisher, SecConst.CERT_ACTIVE, ANY_PROFILEID);
    assertTrue("Status should be success", success);
    assertTrue("Certificate should have been stored", publisher.isWriteCertificateCalled());
  }
  /** Tests that revoking a certificate does not invoke any sampling. */
  public void testStoreCertificateRevoked() throws Exception {
    MockedCertificateSamplerCustomPublisher publisher;
    boolean success;

    publisher = createMockedPublisher(ANY_GOOD_PROPERTIES);
    success = storeCertificate(publisher, SecConst.CERT_REVOKED, ANY_PROFILEID);
    assertTrue("Status should be success", success);
    assertFalse("Certificate should not have been stored", publisher.isWriteCertificateCalled());

    publisher = createMockedPublisher(ANY_GOOD_PROPERTIES);
    success = storeCertificate(publisher, SecConst.CERT_INACTIVE, ANY_PROFILEID);
    assertTrue("Status should be success", success);
    assertFalse("Certificate should not have been stored", publisher.isWriteCertificateCalled());
  }
  /** Tests that testConnection gives error if there is an invalid profile key. */
  public void testInvalidProfileKey() throws Exception {
    MockedCertificateSamplerCustomPublisher publisher;
    Properties config;

    // Profile pvalue=-0.5 (illegal)
    config = new Properties();
    config.setProperty("outputfolder", TEMP_DIR.getAbsolutePath());
    config.setProperty("default.samplingmethod", "SAMPLE_ALL");
    config.setProperty("profileid.INVALID.samplingmethod", "SAMPLE_ALL");

    publisher = createMockedPublisher(config);
    try {
      publisher.testConnection(ANY_ADMIN);
      fail("Should have failed as 'INVALID' is not an legal profile id");
    } catch (PublisherConnectionException expected) {
    } // NOPMD
  }
  /**
   * Tests that testConnection and storeCertificate gives error if there is an invalid sampling
   * method.
   */
  public void testInvalidSamplingMethod() throws Exception {
    MockedCertificateSamplerCustomPublisher publisher;
    Properties config;

    // Default sampling method: INVALID
    config = new Properties();
    config.setProperty("outputfolder", TEMP_DIR.getAbsolutePath());
    config.setProperty("default.samplingmethod", "_INVALID_");

    publisher = createMockedPublisher(config);
    try {
      publisher.testConnection(ANY_ADMIN);
      fail("Should have failed as '_INVALID_' is not an existing sampling method");
    } catch (PublisherConnectionException expected) {
    } // NOPMD
    publisher = createMockedPublisher(config);
    try {
      storeCertificate(publisher, SecConst.CERT_ACTIVE, ANY_PROFILEID);
      fail("Should have failed as '_INVALID_' is not an existing sampling method");
    } catch (PublisherException expected) {
    } // NOPMD

    // Profile sampling method: INVALID
    config = new Properties();
    config.setProperty("outputfolder", TEMP_DIR.getAbsolutePath());
    config.setProperty("default.samplingmethod", "SAMPLE_ALL");
    config.setProperty("profileid." + PROFILE_A + ".samplingmethod", "_INVALID_");

    publisher = createMockedPublisher(config);
    try {
      publisher.testConnection(ANY_ADMIN);
      fail("Should have failed as '_INVALID_' is not an existing sampling method");
    } catch (PublisherConnectionException expected) {
    } // NOPMD
    publisher = createMockedPublisher(config);
    try {
      storeCertificate(publisher, SecConst.CERT_ACTIVE, PROFILE_A);
      fail("Should have failed as '_INVALID_' is not an existing sampling method");
    } catch (PublisherException expected) {
    } // NOPMD
  }
  /**
   * Tests that storeCertificate and testConnection throws Exception as the property for the default
   * sampling method is missing.
   */
  public void testNoDefaultSamplingMethod() throws Exception {
    MockedCertificateSamplerCustomPublisher publisher;
    Properties config = new Properties();

    config.setProperty("outputfolder", TEMP_DIR.getAbsolutePath());

    // Test storeCertificate
    publisher = createMockedPublisher(config);
    try {
      storeCertificate(publisher, SecConst.CERT_ACTIVE, ANY_PROFILEID);
      fail("Should have failed as property outputfolder was missing");
    } catch (PublisherException expected) {
    } // NOPMD

    // Test testConnection
    publisher = createMockedPublisher(config);
    try {
      publisher.testConnection(ANY_ADMIN);
      fail("Should have failed as property outputfolder was missing");
    } catch (PublisherConnectionException expected) {
    } // NOPMD
  }
  /**
   * Tests that storeCertificate and testConnection throws Exception as the property output folder
   * is missing.
   */
  public void testNoOutputFolder() throws Exception {
    MockedCertificateSamplerCustomPublisher publisher;
    Properties config = new Properties();

    config.setProperty("default.samplingmethod", "SAMPLE_ALL");

    // Test storeCertificate
    publisher = createMockedPublisher(config);
    try {
      storeCertificate(publisher, SecConst.CERT_ACTIVE, ANY_PROFILEID);
      fail("Should have failed as property outputfolder was missing");
    } catch (PublisherException expected) {
    } // NOPMD

    // Test testConnection
    publisher = createMockedPublisher(config);
    try {
      publisher.testConnection(ANY_ADMIN);
      fail("Should have failed as property outputfolder was missing");
    } catch (PublisherConnectionException expected) {
    } // NOPMD
  }
  /**
   * Tests that storeCertificate and testConnection throws Exception as the pvalue for a profile is
   * missing.
   */
  public void testNoPValueForProfileSamplingMethod() throws Exception {
    MockedCertificateSamplerCustomPublisher publisher;
    Properties config = new Properties();

    config.setProperty("outputfolder", TEMP_DIR.getAbsolutePath());
    config.setProperty("default.samplingmethod", "SAMPLE_ALL");
    config.setProperty("profileid." + PROFILE_A + ".samplingmethod", "SAMPLE_PROBABILISTIC");

    // Test storeCertificate
    publisher = createMockedPublisher(config);
    try {
      storeCertificate(publisher, SecConst.CERT_ACTIVE, PROFILE_A);
      fail("Should have failed as no default pvalue for profile A specified");
    } catch (PublisherException expected) {
    } // NOPMD

    // Test testConnection
    publisher = createMockedPublisher(config);
    try {
      publisher.testConnection(ANY_ADMIN);
      fail("Should have failed as no pvalue for a profile specified");
    } catch (PublisherConnectionException expected) {
    } // NOPMD
  }
  /**
   * Tests sampling with different probabilities. This method has a change of false positives but
   * with <code>PROBABILISTIC_TRIES</code> number of tries the probability should be small.
   */
  public void testSampleProbabilistic() throws Exception {
    MockedCertificateSamplerCustomPublisher publisher;
    boolean success;

    // Test that with p=0.0 no certificate is stored
    Properties default0 = new Properties();
    default0.setProperty("outputfolder", TEMP_DIR.getAbsolutePath());
    default0.setProperty("default.samplingmethod", "SAMPLE_PROBABILISTIC");
    default0.setProperty("default.pvalue", "0.0");
    for (int i = 0; i < PROBABILISTIC_TRIES; i++) {
      publisher = createMockedPublisher(default0);
      success = storeCertificate(publisher, SecConst.CERT_ACTIVE, ANY_PROFILEID);
      assertTrue("Status should be success", success);
      assertFalse(
          "Certificate should not have been stored, i=" + i, publisher.isWriteCertificateCalled());
    }

    // Test that with pvalue=1.0 all certificates are stored
    Properties default1 = new Properties();
    default1.setProperty("outputfolder", TEMP_DIR.getAbsolutePath());
    default1.setProperty("default.samplingmethod", "SAMPLE_PROBABILISTIC");
    default1.setProperty("default.pvalue", "1.0");
    for (int i = 0; i < PROBABILISTIC_TRIES; i++) {
      publisher = createMockedPublisher(default1);
      success = storeCertificate(publisher, SecConst.CERT_ACTIVE, ANY_PROFILEID);
      assertTrue("Status should be success", success);
      assertTrue(
          "Certificate should have been stored, i=" + i, publisher.isWriteCertificateCalled());
      publisher.reset();
    }

    // Test that with pvalue=0.5 at least some certificates are stored
    Properties default05 = new Properties();
    default05.setProperty("outputfolder", TEMP_DIR.getAbsolutePath());
    default05.setProperty("default.samplingmethod", "SAMPLE_PROBABILISTIC");
    default05.setProperty("default.pvalue", "0.5");
    int stored = 0;
    for (int i = 0; i < PROBABILISTIC_TRIES; i++) {
      publisher = createMockedPublisher(default05);
      success = storeCertificate(publisher, SecConst.CERT_ACTIVE, ANY_PROFILEID);
      assertTrue("Status should be success", success);

      if (publisher.isWriteCertificateCalled()) {
        stored++;
      }
      publisher.reset();
    }
    assertTrue("At least some should have been stored", stored > 0);
  }
 /** Create mocked publisher wrapper. */
 private MockedCertificateSamplerCustomPublisher createMockedPublisher(Properties properties) {
   MockedCertificateSamplerCustomPublisher result = new MockedCertificateSamplerCustomPublisher();
   result.init(properties);
   return result;
 }