/** Tests that a third-party service that fails in dispose */
  @Test
  public void testFailingInDisposeThirdPartyService() {
    ServiceLocator locator = LocatorHelper.getServiceLocator(RecordingErrorService.class);

    AlwaysFailInDisposeActiveDescriptor thirdPartyDescriptor =
        new AlwaysFailInDisposeActiveDescriptor();

    ServiceLocatorUtilities.addOneDescriptor(locator, thirdPartyDescriptor);

    ActiveDescriptor<?> serviceDescriptor =
        locator.getBestDescriptor(
            BuilderHelper.createContractFilter(SimpleService.class.getName()));
    Assert.assertNotNull(serviceDescriptor);

    ServiceHandle<SimpleService> handle = locator.getServiceHandle(SimpleService.class);
    Assert.assertNotNull(handle);
    Assert.assertNotNull(handle.getService());

    handle.destroy();

    List<ErrorInformation> errors =
        locator.getService(RecordingErrorService.class).getAndClearErrors();

    Assert.assertEquals(1, errors.size());

    ErrorInformation ei = errors.get(0);

    Assert.assertEquals(ErrorType.SERVICE_DESTRUCTION_FAILURE, ei.getErrorType());
    Assert.assertEquals(serviceDescriptor, ei.getDescriptor());
    Assert.assertNull(ei.getInjectee());

    Throwable associatedException = ei.getAssociatedException();
    Assert.assertTrue(associatedException.getMessage().contains(ERROR_STRING));
  }
  /**
   * Tests that a service that fails in the constructor has the error passed to the error service
   */
  @Test
  public void testServiceFailsInConstructor() {
    ServiceLocator locator =
        LocatorHelper.getServiceLocator(
            RecordingErrorService.class, ServiceFailsInConstructor.class);

    ActiveDescriptor<?> serviceDescriptor =
        locator.getBestDescriptor(
            BuilderHelper.createContractFilter(ServiceFailsInConstructor.class.getName()));
    Assert.assertNotNull(serviceDescriptor);

    try {
      locator.getService(ServiceFailsInConstructor.class);
      Assert.fail("Should have failed");
    } catch (MultiException me) {
      Assert.assertTrue(me.getMessage().contains(ERROR_STRING));
    }

    List<ErrorInformation> errors =
        locator.getService(RecordingErrorService.class).getAndClearErrors();

    Assert.assertEquals(1, errors.size());

    ErrorInformation ei = errors.get(0);

    Assert.assertEquals(ErrorType.SERVICE_CREATION_FAILURE, ei.getErrorType());
    Assert.assertEquals(serviceDescriptor, ei.getDescriptor());
    Assert.assertNull(ei.getInjectee());

    Throwable associatedException = ei.getAssociatedException();
    Assert.assertTrue(associatedException.getMessage().contains(ERROR_STRING));
  }
  /**
   * Tests that a service that fails but tells HK2 to NOT report the failure to the error handler
   * service
   */
  @Test
  public void testSilentFailureInPostConstruct() {
    ServiceLocator locator =
        LocatorHelper.getServiceLocator(
            RecordingErrorService.class, ServiceDirectsNoErrorService.class);

    ActiveDescriptor<?> serviceDescriptor =
        locator.getBestDescriptor(
            BuilderHelper.createContractFilter(ServiceDirectsNoErrorService.class.getName()));
    Assert.assertNotNull(serviceDescriptor);

    try {
      locator.getService(ServiceDirectsNoErrorService.class);
      Assert.fail("Should have failed");
    } catch (MultiException me) {
      Assert.assertTrue(me.getMessage().contains(ERROR_STRING));
    }

    List<ErrorInformation> errors =
        locator.getService(RecordingErrorService.class).getAndClearErrors();

    Assert.assertEquals(0, errors.size());
  }