@Test
  public void testMultipleManualInstances() throws Exception {
    TaskScheduleUtil.waitForAllTasksToStop();
    getEventInspectorsUtil().waitForCalmPeriod();

    createSnapshotTask("Nexus1650Task1");
    createSnapshotTask("Nexus1650Task2");
    createSnapshotTask("Nexus1650Task3");

    List<ScheduledServiceListResource> tasks = TaskScheduleUtil.getTasks();

    assertThat(tasks, hasSize(3));

    long startTimestamp = System.currentTimeMillis();

    for (ScheduledServiceListResource resource : tasks) {
      TaskScheduleUtil.run(resource.getId());
    }

    waitForOneTaskSleeping();

    TaskScheduleUtil.waitForAllTasksToStop();

    assertAllTasksWereRunning(startTimestamp);
  }
  @Test
  public void test() throws Exception {
    final File nexusDir = new File(nexusWorkDir, "storage/nxcm1381");

    TaskScheduleUtil.run("1");
    TaskScheduleUtil.waitForAllTasksToStop();

    assertThat(
        new File(nexusDir, "features/com.sonatype.nexus.p2.its.feature_1.0.0.jar"), exists());
    assertThat(new File(nexusDir, "plugins/com.sonatype.nexus.p2.its.bundle_1.0.0.jar"), exists());
  }
  @Test
  public void test() throws Exception {
    TaskScheduleUtil.run("1");
    TaskScheduleUtil.waitForAllTasksToStop();

    installAndVerifyP2Feature(
        "com.sonatype.nexus.p2.its.feature3.feature.group",
        new String[] {"com.sonatype.nexus.p2.its.feature3_1.0.0"},
        new String[] {
          "com.sonatype.nexus.p2.its.bundle_1.0.0.jar",
          "com.sonatype.nexus.p2.its.bundle3_1.0.0.jar"
        });
  }
  @Test
  public void publishIndex() throws Exception {
    File repositoryPath = new File(nexusWorkDir, "storage/nexus-test-harness-repo");
    File index = new File(repositoryPath, ".index");

    if (index.exists()) {
      // can't contain the OSS index
      MatcherAssert.assertThat(
          Arrays.asList(index.list()),
          CoreMatchers.not(
              IsCollectionContaining.hasItems(
                  "nexus-maven-repository-index.gz",
                  "nexus-maven-repository-index.gz.md5",
                  "nexus-maven-repository-index.gz.sha1",
                  "nexus-maven-repository-index.properties",
                  "nexus-maven-repository-index.properties.md5",
                  "nexus-maven-repository-index.properties.sha1",
                  "nexus-maven-repository-index.zip",
                  "nexus-maven-repository-index.zip.md5",
                  "nexus-maven-repository-index.zip.sha1")));
    }

    ScheduledServicePropertyResource prop = new ScheduledServicePropertyResource();
    prop.setKey("repositoryOrGroupId");
    prop.setValue("repo_nexus-test-harness-repo");

    TaskScheduleUtil.runTask(PublishIndexesTaskDescriptor.ID, prop);

    Assert.assertTrue(index.exists(), ".index should exists after publish index task was run.");
  }
  protected void createSnapshotTask(String name) throws Exception {
    ScheduledServicePropertyResource repositoryProp = new ScheduledServicePropertyResource();
    repositoryProp.setKey("repositoryId");
    repositoryProp.setValue("nexus-test-harness-snapshot-repo");

    ScheduledServicePropertyResource keepSnapshotsProp = new ScheduledServicePropertyResource();
    keepSnapshotsProp.setKey("minSnapshotsToKeep");
    keepSnapshotsProp.setValue(String.valueOf(0));

    ScheduledServicePropertyResource ageProp = new ScheduledServicePropertyResource();
    ageProp.setKey("removeOlderThanDays");
    ageProp.setValue(String.valueOf(0));

    ScheduledServicePropertyResource removeReleasedProp = new ScheduledServicePropertyResource();
    removeReleasedProp.setKey("removeIfReleaseExists");
    removeReleasedProp.setValue(String.valueOf(true));

    ScheduledServiceBaseResource scheduledTask = new ScheduledServiceBaseResource();
    scheduledTask.setEnabled(true);
    scheduledTask.setId(null);
    scheduledTask.setName(name);
    scheduledTask.setTypeId(SnapshotRemovalTaskDescriptor.ID);
    scheduledTask.setSchedule("manual");
    scheduledTask.addProperty(repositoryProp);
    scheduledTask.addProperty(keepSnapshotsProp);
    scheduledTask.addProperty(ageProp);
    scheduledTask.addProperty(removeReleasedProp);

    Status status = TaskScheduleUtil.create(scheduledTask);

    Assert.assertTrue(status.isSuccess());
  }
  @Test
  public void changeProxyStatusTest() throws Exception {
    // change the name of the test repo
    RepositoryMessageUtil repoUtil =
        new RepositoryMessageUtil(
            this.getXMLXStream(), MediaType.APPLICATION_XML, getRepositoryTypeRegistry());

    RepositoryStatusResource repo = repoUtil.getStatus("release-proxy-repo-1");
    repo.setProxyMode(ProxyMode.BLOCKED_AUTO.name());
    repoUtil.updateStatus(repo);

    TaskScheduleUtil.waitForAllTasksToStop();

    SyndFeed systemFeed = FeedUtil.getFeed("systemChanges");
    this.validateLinksInFeeds(systemFeed);

    SyndFeed systemStatusFeed = FeedUtil.getFeed("systemRepositoryStatusChanges");
    this.validateLinksInFeeds(systemStatusFeed);

    Assert.assertTrue(
        findFeedEntry(
            systemFeed, "Repository proxy mode change", new String[] {"release-proxy-repo-1"}));

    Assert.assertTrue(
        findFeedEntry(
            systemStatusFeed,
            "Repository proxy mode change",
            new String[] {"release-proxy-repo-1"}));
  }
  @Test
  public void testReindex() throws Exception {

    this.repositoryPath = new File(nexusWorkDir, "storage/" + this.getTestRepositoryId());
    logger.info("path: " + repositoryPath);
    File oldSnapshot = getTestFile("repo");

    // Copy artifact to avoid indexing
    FileUtils.copyDirectory(oldSnapshot, repositoryPath);

    // try to seach and fail
    List<NexusArtifact> search = getSearchMessageUtil().searchFor("nexus641");
    Assert.assertEquals(search.size(), 1, "The artifact was already indexed");

    // reindex
    ScheduledServicePropertyResource prop = new ScheduledServicePropertyResource();
    prop.setKey("repositoryId");
    prop.setValue(this.getTestRepositoryId());

    // reindex
    TaskScheduleUtil.runTask(UpdateIndexTaskDescriptor.ID, prop);

    // try to download again and success
    search = getSearchMessageUtil().searchFor("nexus641");
    Assert.assertEquals(search.size(), 2, "The artifact should be indexed");
  }
  @Test
  public void hostedTestRelRepoAndDeployFile() throws IOException, Exception {
    // create a release repository
    String repoId = "tmp-releases";
    RepositoryResource repo = new RepositoryResource();
    repo.setProvider("ivy");
    repo.setFormat("maven2");
    repo.setRepoPolicy("release");
    repo.setChecksumPolicy("ignore");
    repo.setBrowseable(false);

    repo.setId(repoId);
    repo.setName(repoId);
    repo.setRepoType("hosted");
    repo.setWritePolicy(RepositoryWritePolicy.ALLOW_WRITE.name());
    repo.setDownloadRemoteIndexes(true);
    repo.setBrowseable(true);
    repo.setRepoPolicy(RepositoryPolicy.RELEASE.name());
    repo.setChecksumPolicy(ChecksumPolicy.IGNORE.name());

    repo.setIndexable(true); // being sure!!!
    repoUtil.createRepository(repo);

    // firstly assert that repository is there
    repo = (RepositoryResource) repoUtil.getRepository(repoId);
    Assert.assertTrue(repo.isIndexable());

    TaskScheduleUtil.waitForAllTasksToStop();

    // then deploy a release artifact
    Gav gav = GavUtil.newGav("ivyRemover", "auth-mod", "1.0");
    getDeployUtils().deployUsingGavWithRest(repoId, gav, getTestFile("simple-artifact.jar"));

    TaskScheduleUtil.waitForAllTasksToStop();
    getEventInspectorsUtil().waitForCalmPeriod();

    // secondly assert that the artifact is in the release repository
    List<NexusArtifact> result = getSearchMessageUtil().searchForGav(gav, repoId);
    Assert.assertEquals(
        result.size(), 1, "Results: \n" + XStreamFactory.getXmlXStream().toXML(result));

    // thirdly assert that there is at least alltogether one release artifact in the release
    // repository
    result = getSearchMessageUtil().searchFor(Collections.singletonMap("q", "ivyRemover"), repoId);
    Assert.assertEquals(
        result.size(), 1, "Results: \n" + XStreamFactory.getXmlXStream().toXML(result));
  }
  @Test
  public void bootEventTest() throws Exception {
    TaskScheduleUtil.waitForAllTasksToStop();

    SyndFeed feed = FeedUtil.getFeed("systemChanges");
    this.validateLinksInFeeds(feed);
    Assert.assertTrue(findFeedEntry(feed, "Booting", null));
  }
  private void assertAllTasksWereRunning(long startTimestamp) throws IOException {
    final List<ScheduledServiceListResource> tasks = TaskScheduleUtil.getTasks();

    for (ScheduledServiceListResource task : tasks) {
      assertThat(
          "task did not run properly!", task.getLastRunTimeInMillis(), greaterThan(startTimestamp));
    }
  }
  @Test
  public void test() throws Exception {
    final File nexusDir = new File(nexusWorkDir + "/storage/nxcm0670");
    final File remoteDir = new File(localStorageDir + "/nxcm0670");

    TaskScheduleUtil.run("1");
    TaskScheduleUtil.waitForAllTasksToStop();

    assertThat(new File(nexusDir, "plugins/com.sonatype.nexus.p2.its.bundle_1.0.0.jar"), exists());

    copyFile(new File(remoteDir, "site-empty.xml"), new File(remoteDir, "site.xml"));

    TaskScheduleUtil.run("1");
    TaskScheduleUtil.waitForAllTasksToStop();

    assertThat(
        new File(nexusDir, "plugins/com.sonatype.nexus.p2.its.bundle_1.0.0.jar"), not(exists()));
  }
  protected void downloadApacheFelixWebManagement(final String repoId)
      throws IOException, Exception, MalformedURLException {
    FileUtils.deleteDirectory(new File(FELIX_HOME, "felix-cache"));

    final ScheduledServicePropertyResource prop = new ScheduledServicePropertyResource();
    prop.setKey("repositoryId");
    prop.setValue(repoId);

    TaskScheduleUtil.runTask("PublishObrDescriptorTask", prop);

    downloadFile(
        new URL(getRepositoryUrl(repoId) + ".meta/obr.xml"),
        "target/" + getTestId() + "/download/obr.xml");

    final ProcessBuilder pb =
        new ProcessBuilder(
            "java", "-Dfelix.config.properties=" + FELIX_CONF.toURI(), "-jar", "bin/felix.jar");

    pb.directory(FELIX_HOME);
    pb.redirectErrorStream(true);
    final Process p = pb.start();

    final Object lock = new Object();

    final Thread t =
        new Thread(
            new Runnable() {
              public void run() {
                // just a safeguard, if felix get stuck kill everything
                try {
                  synchronized (lock) {
                    lock.wait(5 * 1000 * 60);
                  }
                } catch (final InterruptedException e) {
                  // ignore
                }
                p.destroy();
              }
            });
    t.setDaemon(true);
    t.start();

    synchronized (lock) {
      final InputStream input = p.getInputStream();
      final OutputStream output = p.getOutputStream();
      waitFor(input, "g!");
      output.write(("obr:repos add " + getRepositoryUrl(repoId) + ".meta/obr.xml\r\n").getBytes());
      output.flush();
      waitFor(input, "g!");
      output.write("obr:deploy -s org.apache.felix.webconsole\r\n".getBytes());
      output.flush();
      waitFor(input, "done.");
      p.destroy();

      lock.notifyAll();
    }
  }
  private RepositoryResource setWritePolicy(String repoId, RepositoryWritePolicy policy)
      throws Exception {
    RepositoryResource repo = (RepositoryResource) this.repoUtil.getRepository(repoId);
    repo.setWritePolicy(policy.name());
    repo = (RepositoryResource) this.repoUtil.updateRepo(repo);

    TaskScheduleUtil.waitForAllTasksToStop();

    return repo;
  }
  @Test
  public void testIndexOptimizer() throws Exception {
    // reindex
    ScheduledServicePropertyResource prop = new ScheduledServicePropertyResource();
    prop.setKey("repositoryId");
    prop.setValue("nexus-test-harness-repo");

    // reindex
    TaskScheduleUtil.runTask(OptimizeIndexTaskDescriptor.ID, prop);
  }
  private boolean isAtLeastOneSleeping() throws Exception {
    List<ScheduledServiceListResource> tasks = TaskScheduleUtil.getTasks();

    for (ScheduledServiceListResource resource : tasks) {
      if (resource.getStatus().equals("SLEEPING")) {
        return true;
      }
    }

    return false;
  }
  @Test
  public void expireAllRepos() throws Exception {
    ScheduledServicePropertyResource prop = new ScheduledServicePropertyResource();
    prop.setKey("repositoryId");
    prop.setValue("all_repo");

    ScheduledServicePropertyResource age = new ScheduledServicePropertyResource();
    age.setKey("evictOlderCacheItemsThen");
    age.setValue(String.valueOf(10));

    TaskScheduleUtil.runTask(EvictUnusedItemsTaskDescriptor.ID, prop, age);
  }
  @Test
  public void rebuildAttributes() throws Exception {
    String attributePath = "proxy/attributes/nexus-test-harness-repo/nexus640/artifact/1.0.0/";

    ScheduledServicePropertyResource repo = new ScheduledServicePropertyResource();
    repo.setKey("repositoryOrGroupId");
    repo.setValue("repo_" + REPO_TEST_HARNESS_REPO);
    TaskScheduleUtil.runTask(RebuildAttributesTaskDescriptor.ID, repo);

    File jar = new File(nexusWorkDir, attributePath + "artifact-1.0.0.jar");
    Assert.assertTrue(jar.exists(), "Attribute files should be generated after rebuild");
    File pom = new File(nexusWorkDir, attributePath + "artifact-1.0.0.pom");
    Assert.assertTrue(pom.exists(), "Attribute files should be generated after rebuild");
  }
  @Test
  public void updateRepoTest() throws Exception {
    // change the name of the test repo
    RepositoryMessageUtil repoUtil =
        new RepositoryMessageUtil(
            this.getXMLXStream(), MediaType.APPLICATION_XML, getRepositoryTypeRegistry());

    RepositoryBaseResource repo = repoUtil.getRepository(this.getTestRepositoryId());
    String oldName = repo.getName();
    String newName = repo.getName() + "-new";
    repo.setName(newName);
    repoUtil.updateRepo(repo);

    TaskScheduleUtil.waitForAllTasksToStop();

    final SyndFeed feed = FeedUtil.getFeed("systemChanges");
    this.validateLinksInFeeds(feed);
    Assert.assertTrue(
        "Update repo feed not found\r\n\r\n" + feed,
        findFeedEntry(feed, "Configuration change", new String[] {newName, oldName}));
  }
  @Test
  @Ignore("Test is unstable - needs to be rewritten or replaced. See NEXUS-4606")
  public void doConcurrence() throws Exception {
    List<Thread> threads = new ArrayList<Thread>();
    final Map<Thread, Throwable> errors = new LinkedHashMap<Thread, Throwable>();
    for (final File f : files) {
      Thread t =
          new Thread(
              new Runnable() {

                public void run() {
                  try {
                    Verifier v =
                        MavenDeployer.deployAndGetVerifier(
                            GavUtil.newGav("nexus2497", "concurrence", "1.0-SNAPSHOT"),
                            getRepositoryUrl(REPO_TEST_HARNESS_SNAPSHOT_REPO),
                            f,
                            getOverridableFile("settings.xml"));

                    v.verifyErrorFreeLog();
                  } catch (Exception e) {
                    throw new RuntimeException(e);
                  }
                }
              });
      t.setUncaughtExceptionHandler(
          new UncaughtExceptionHandler() {
            public void uncaughtException(Thread t, Throwable e) {
              errors.put(t, e);
            }
          });

      threads.add(t);
    }

    ScheduledServicePropertyResource repo = new ScheduledServicePropertyResource();
    repo.setKey("repositoryId");
    repo.setValue(REPO_TEST_HARNESS_SNAPSHOT_REPO);
    TaskScheduleUtil.runTask(TASK_NAME, RebuildMavenMetadataTaskDescriptor.ID, repo);

    // uploads while rebuilding
    for (Thread thread : threads) {
      thread.start();
      Thread.yield();
    }

    // w8 for uploads
    for (Thread thread : threads) {
      thread.join();
    }

    TaskScheduleUtil.waitForAllTasksToStop(RebuildMavenMetadataTask.class);

    if (!errors.isEmpty()) {
      Set<Entry<Thread, Throwable>> entries = errors.entrySet();
      ByteArrayOutputStream str = new ByteArrayOutputStream();
      PrintStream s = new PrintStream(str);
      for (Entry<Thread, Throwable> entry : entries) {
        s.append(entry.getKey().getName());
        s.append("\n");
        entry.getValue().printStackTrace(s);
        s.append("\n");
        s.append("\n");
      }

      Assert.fail("Found some errors deploying:\n" + str.toString());
    }
    Assert.assertEquals(TaskScheduleUtil.getStatus(TASK_NAME), "Ok");
  }
  @Test
  public void testSnapRepoDeployFilesRunTaskDeleteIFRelease() throws IOException, Exception {

    // create a snapshot repository
    createSnapshotRepo(snapRepoId);

    // add some artifacts
    copyToSnapRepo(snapRepoId);

    TaskScheduleUtil.waitForAllTasksToStop();

    // update indexes for search
    RepositoryMessageUtil.updateIndexes(snapRepoId);

    TaskScheduleUtil.waitForAllTasksToStop();

    // set Remover task parameters 2 latest version snapshots should be left over
    ScheduledServicePropertyResource keepSnapshotsProp = new ScheduledServicePropertyResource();
    keepSnapshotsProp.setKey(IVYSnapshotRemovalTaskDescriptor.MIN_TO_KEEP_FIELD_ID);
    keepSnapshotsProp.setValue(String.valueOf(2));

    ScheduledServicePropertyResource ageProp = new ScheduledServicePropertyResource();
    ageProp.setKey(IVYSnapshotRemovalTaskDescriptor.KEEP_DAYS_FIELD_ID);
    ageProp.setValue(String.valueOf(0));

    // and if a release version exists it should be removed too
    ScheduledServicePropertyResource relProp = new ScheduledServicePropertyResource();
    relProp.setKey(IVYSnapshotRemovalTaskDescriptor.REMOVE_WHEN_RELEASED_FIELD_ID);
    relProp.setValue(Boolean.toString(true));

    ScheduledServicePropertyResource repos = new ScheduledServicePropertyResource();
    repos.setKey("IvyRepositoryId");
    repos.setValue(snapRepoId);
    TaskScheduleUtil.runTask(
        "IvySnapshotRemoval",
        IVYSnapshotRemovalTaskDescriptor.ID,
        repos,
        keepSnapshotsProp,
        ageProp,
        relProp);

    TaskScheduleUtil.waitForAllTasksToStop();
    getEventInspectorsUtil().waitForCalmPeriod();

    // firstly assert that there is the artifact "auth-api" version "0.8-102" left over with
    // ".source.jar" and ".jar"
    Gav gav = GavUtil.newGav("ivyRemover", "auth-api", "0.8-102");

    List<NexusArtifact> result = getSearchMessageUtil().searchForGav(gav, snapRepoId);

    Assert.assertEquals(
        result.size(), 2, "Results: \n" + XStreamFactory.getXmlXStream().toXML(result));

    // secondly assert that there is the artifact "auth-api" version "0.8-103" left over with
    // ".source.jar" and ".jar"
    gav = GavUtil.newGav("ivyRemover", "auth-api", "0.8-103");

    result = getSearchMessageUtil().searchForGav(gav, snapRepoId);
    Assert.assertEquals(
        result.size(), 2, "Results: \n" + XStreamFactory.getXmlXStream().toXML(result));

    // thirdly assert that there isn't the artifact "auth-mod" version "0.8-102" left over
    gav = GavUtil.newGav("ivyRemover", "auth-mod", "1.0-102");

    result = getSearchMessageUtil().searchForGav(gav, snapRepoId);
    Assert.assertEquals(
        result.size(), 0, "Results: \n" + XStreamFactory.getXmlXStream().toXML(result));

    // fourthly assert that there isn't the artifact "auth-api" version "0.8-103" left over
    gav = GavUtil.newGav("ivyRemover", "auth-mod", "1.0-103");

    result = getSearchMessageUtil().searchForGav(gav, snapRepoId);
    Assert.assertEquals(
        result.size(), 0, "Results: \n" + XStreamFactory.getXmlXStream().toXML(result));

    // fifthly assert that there are at least 2 of 8 snapshots with 2 jar files in the whole test
    // group, 6 removed
    result =
        getSearchMessageUtil().searchFor(Collections.singletonMap("q", "ivyRemover"), snapRepoId);
    Assert.assertEquals(
        result.size(), 4, "Results: \n" + XStreamFactory.getXmlXStream().toXML(result));
  }