@Test
  public void testProcessEndtimeUpdate() throws Exception {
    scheduleProcess();
    waitForBundleStart(Job.Status.RUNNING);

    ClientResponse response =
        this.service
            .path("api/entities/definition/process/" + processName)
            .header("Remote-User", REMOTE_USER)
            .accept(MediaType.TEXT_XML)
            .get(ClientResponse.class);
    Process process =
        (Process)
            EntityType.PROCESS
                .getUnmarshaller()
                .unmarshal(new StringReader(response.getEntity(String.class)));

    Validity processValidity = process.getClusters().getClusters().get(0).getValidity();
    processValidity.setEnd(new Date(new Date().getTime() + 60 * 60 * 1000));
    File tmpFile = getTempFile();
    EntityType.PROCESS.getMarshaller().marshal(process, tmpFile);
    response =
        this.service
            .path("api/entities/update/process/" + processName)
            .header("Remote-User", REMOTE_USER)
            .accept(MediaType.TEXT_XML)
            .post(ClientResponse.class, getServletInputStream(tmpFile.getAbsolutePath()));
    assertSuccessful(response);

    // Assert that update does not create new bundle
    List<BundleJob> bundles = getBundles();
    Assert.assertEquals(bundles.size(), 1);
  }
  /**
   * Tests should be enabled only in local environments as they need running instance of webserver
   */
  @Test
  public void testUpdateCheckUser() throws Exception {
    Map<String, String> overlay = getUniqueOverlay();
    String tmpFileName = overlayParametersOverTemplate(PROCESS_TEMPLATE, overlay);
    Process process =
        (Process) EntityType.PROCESS.getUnmarshaller().unmarshal(new File(tmpFileName));
    Validity processValidity = process.getClusters().getClusters().get(0).getValidity();
    processValidity.setEnd(new Date(new Date().getTime() + 2 * 24 * 60 * 60 * 1000));
    File tmpFile = getTempFile();
    EntityType.PROCESS.getMarshaller().marshal(process, tmpFile);
    scheduleProcess(tmpFile.getAbsolutePath(), overlay);
    waitForBundleStart(Status.RUNNING);

    List<BundleJob> bundles = getBundles();
    Assert.assertEquals(bundles.size(), 1);
    Assert.assertEquals(bundles.get(0).getUser(), REMOTE_USER);

    ClientResponse response =
        this.service
            .path("api/entities/definition/feed/" + outputFeedName)
            .header("Remote-User", REMOTE_USER)
            .accept(MediaType.TEXT_XML)
            .get(ClientResponse.class);
    Feed feed =
        (Feed)
            EntityType.FEED
                .getUnmarshaller()
                .unmarshal(new StringReader(response.getEntity(String.class)));

    // change output feed path and update feed as another user
    feed.getLocations()
        .getLocations()
        .get(0)
        .setPath("/ivory/test/output2/${YEAR}/${MONTH}/${DAY}");
    tmpFile = getTempFile();
    EntityType.FEED.getMarshaller().marshal(feed, tmpFile);
    response =
        this.service
            .path("api/entities/update/feed/" + outputFeedName)
            .header("Remote-User", "testuser")
            .accept(MediaType.TEXT_XML)
            .post(ClientResponse.class, getServletInputStream(tmpFile.getAbsolutePath()));
    assertSuccessful(response);

    bundles = getBundles();
    Assert.assertEquals(bundles.size(), 2);
    Assert.assertEquals(bundles.get(0).getUser(), REMOTE_USER);
    Assert.assertEquals(bundles.get(1).getUser(), REMOTE_USER);
  }
  @Test
  public void testProcessInputUpdate() throws Exception {
    scheduleProcess();
    waitForBundleStart(Job.Status.RUNNING);

    ClientResponse response =
        this.service
            .path("api/entities/definition/process/" + processName)
            .header("Remote-User", REMOTE_USER)
            .accept(MediaType.TEXT_XML)
            .get(ClientResponse.class);
    Process process =
        (Process)
            EntityType.PROCESS
                .getUnmarshaller()
                .unmarshal(new StringReader(response.getEntity(String.class)));

    String feed3 = "f3" + System.currentTimeMillis();
    Map<String, String> overlay = new HashMap<String, String>();
    overlay.put("inputFeedName", feed3);
    overlay.put("cluster", clusterName);
    response = submitToIvory(FEED_TEMPLATE1, overlay, EntityType.FEED);
    assertSuccessful(response);

    Input input = new Input();
    input.setFeed(feed3);
    input.setName("inputData2");
    input.setStart("today(20,0)");
    input.setEnd("today(20,20)");
    process.getInputs().getInputs().add(input);

    Validity processValidity = process.getClusters().getClusters().get(0).getValidity();
    processValidity.setEnd(new Date(new Date().getTime() + 2 * 24 * 60 * 60 * 1000));
    File tmpFile = getTempFile();
    EntityType.PROCESS.getMarshaller().marshal(process, tmpFile);
    response =
        this.service
            .path("api/entities/update/process/" + processName)
            .header("Remote-User", REMOTE_USER)
            .accept(MediaType.TEXT_XML)
            .post(ClientResponse.class, getServletInputStream(tmpFile.getAbsolutePath()));
    assertSuccessful(response);

    // Assert that update creates new bundle
    List<BundleJob> bundles = getBundles();
    Assert.assertEquals(bundles.size(), 2);
  }
  @Test
  public void testProcessDeleteAndSchedule() throws Exception {
    // Submit process with invalid property so that coord submit fails and bundle goes to failed
    // state
    Map<String, String> overlay = getUniqueOverlay();
    String tmpFileName = overlayParametersOverTemplate(PROCESS_TEMPLATE, overlay);
    Process process =
        (Process) EntityType.PROCESS.getUnmarshaller().unmarshal(new File(tmpFileName));
    Property prop = new Property();
    prop.setName("newProp");
    prop.setValue("${formatTim()}");
    process.getProperties().getProperties().add(prop);
    File tmpFile = getTempFile();
    EntityType.PROCESS.getMarshaller().marshal(process, tmpFile);
    scheduleProcess(tmpFile.getAbsolutePath(), overlay);
    waitForBundleStart(Status.FAILED);

    // Delete and re-submit the process with correct workflow
    ClientResponse clientRepsonse =
        this.service
            .path("api/entities/delete/process/" + processName)
            .header("Remote-User", REMOTE_USER)
            .accept(MediaType.TEXT_XML)
            .delete(ClientResponse.class);
    assertSuccessful(clientRepsonse);
    process.getWorkflow().setPath("/ivory/test/workflow");
    tmpFile = getTempFile();
    EntityType.PROCESS.getMarshaller().marshal(process, tmpFile);
    clientRepsonse =
        this.service
            .path("api/entities/submitAndSchedule/process")
            .header("Remote-User", REMOTE_USER)
            .accept(MediaType.TEXT_XML)
            .type(MediaType.TEXT_XML)
            .post(ClientResponse.class, getServletInputStream(tmpFile.getAbsolutePath()));
    assertSuccessful(clientRepsonse);

    // Assert that new schedule creates new bundle
    List<BundleJob> bundles = getBundles();
    Assert.assertEquals(bundles.size(), 2);
  }
  @Test(enabled = false)
  public void testOptionalInput() throws Exception {
    Map<String, String> overlay = getUniqueOverlay();
    String tmpFileName = overlayParametersOverTemplate(PROCESS_TEMPLATE, overlay);
    Process process =
        (Process) EntityType.PROCESS.getUnmarshaller().unmarshal(new File(tmpFileName));

    Input in1 = process.getInputs().getInputs().get(0);
    Input in2 = new Input();
    in2.setFeed(in1.getFeed());
    in2.setName("input2");
    in2.setOptional(true);
    in2.setPartition(in1.getPartition());
    in2.setStart("now(-1,0)");
    in2.setEnd("now(0,0)");
    process.getInputs().getInputs().add(in2);

    File tmpFile = getTempFile();
    EntityType.PROCESS.getMarshaller().marshal(process, tmpFile);
    scheduleProcess(tmpFile.getAbsolutePath(), overlay);
    waitForWorkflowStart(processName);
  }