private boolean updateExistingJob(AbstractProject<?, ?> project, String config) {
    boolean created;

    // Leverage XMLUnit to perform diffs
    Diff diff;
    try {
      String oldJob = project.getConfigFile().asString();
      diff = XMLUnit.compareXML(oldJob, config);
      if (diff.similar()) {
        LOGGER.log(Level.FINE, String.format("Project %s is identical", project.getName()));
        return false;
      }
    } catch (Exception e) {
      // It's not a big deal if we can't diff, we'll just move on
      LOGGER.warning(e.getMessage());
    }

    // TODO Perform comparison between old and new, and print to console
    // TODO Print out, for posterity, what the user might have changed, in the format of the DSL

    LOGGER.log(Level.FINE, String.format("Updating project %s as %s", project.getName(), config));
    StreamSource streamSource =
        new StreamSource(new StringReader(config)); // TODO use real xmlReader
    try {
      project.updateByXml(streamSource);
      created = true;
    } catch (IOException ioex) {
      LOGGER.log(Level.WARNING, String.format("Error writing updated project to file."), ioex);
      created = false;
    }
    return created;
  }
  @Override
  public CauseOfBlockage canRun(Queue.Item item) {
    // Skip locking for multiple configuration projects,
    // only the child jobs will actually lock resources.
    if (item.task instanceof MatrixProject) return null;

    AbstractProject<?, ?> project = Utils.getProject(item);
    if (project == null) return null;

    LockableResourcesStruct resources = Utils.requiredResources(project);
    if (resources == null || (resources.required.isEmpty() && resources.label.isEmpty())) {
      return null;
    }

    int resourceNumber;
    try {
      resourceNumber = Integer.parseInt(resources.requiredNumber);
    } catch (NumberFormatException e) {
      resourceNumber = 0;
    }

    LOGGER.finest(project.getName() + " trying to get resources with these details: " + resources);

    if (resourceNumber > 0 || !resources.label.isEmpty()) {
      Map<String, Object> params = new HashMap<String, Object>();
      if (item.task instanceof MatrixConfiguration) {
        MatrixConfiguration matrix = (MatrixConfiguration) item.task;
        params.putAll(matrix.getCombination());
      }

      List<LockableResource> selected =
          LockableResourcesManager.get()
              .queue(resources, item.id, project.getFullName(), resourceNumber, params, LOGGER);

      if (selected != null) {
        LOGGER.finest(project.getName() + " reserved resources " + selected);
        return null;
      } else {
        LOGGER.finest(project.getName() + " waiting for resources");
        return new BecauseResourcesLocked(resources);
      }

    } else {
      if (LockableResourcesManager.get().queue(resources.required, item.id)) {
        LOGGER.finest(project.getName() + " reserved resources " + resources.required);
        return null;
      } else {
        LOGGER.finest(project.getName() + " waiting for resources " + resources.required);
        return new BecauseResourcesLocked(resources);
      }
    }
  }
  public InheritanceParametersDefinitionProperty(
      AbstractProject<?, ?> owner, ParametersDefinitionProperty other) {
    this(owner, other.getParameterDefinitions());
    // Then, we copy the scope
    if (other instanceof InheritanceParametersDefinitionProperty) {
      InheritanceParametersDefinitionProperty ipdp =
          (InheritanceParametersDefinitionProperty) other;

      ipdp.scopeLock.readLock().lock();
      this.scopeLock.writeLock().lock();
      try {
        for (String pName : ipdp.fullScope.keySet()) {
          List<ScopeEntry> oLst = ipdp.fullScope.get(pName);
          if (oLst == null) {
            continue;
          }
          LinkedList<ScopeEntry> newLst = new LinkedList<ScopeEntry>();
          for (ScopeEntry entry : oLst) {
            newLst.add(new ScopeEntry(entry.owner, entry.param));
          }
          this.fullScope.put(pName, newLst);
        }
      } finally {
        this.scopeLock.writeLock().unlock();
        ipdp.scopeLock.readLock().unlock();
      }
    } else {
      this.addScopedParameterDefinitions(
          (owner != null) ? owner.getName() : "", other.getParameterDefinitions());
    }
  }
Пример #4
0
  public void populate(@NotNull AbstractProject project) {
    synchronized (populateLock) {
      Run lastBuild = project.getLastBuild();
      if (lastBuild == null) {
        return;
      }

      if (lastBuild.getNumber() <= oldest) {
        return;
      }

      for (int number = lastBuild.getNumber(); number > oldest; number--) {
        Run build = project.getBuildByNumber(number);
        if (build == null) {
          continue;
        }
        String externalizableId = build.getExternalizableId();

        size++;
        put("projectName", project.getName(), externalizableId);
        populateWithChangeInformation(build, externalizableId);
        populateWithCauseInformation(build, externalizableId);
        populateWithParameters(build, externalizableId);
      }

      oldest = lastBuild.getNumber();
    }
  }
  @Test
  public void assertJobNameWithoutComputerIsResolved() {
    when(project.getName()).thenReturn("ThisIsAJob");

    BuildVariableResolver resolver = new BuildVariableResolver(project);
    assertEquals("Variable resolution was incorrect", "ThisIsAJob", resolver.resolve("JOB_NAME"));
    assertNull("Variable resolution was performed", resolver.resolve("NONE_EXISTING_KEY"));
  }
  @Test
  public void assertJobNameIsResolved() {
    when(project.getName()).thenReturn("ThisIsAJob");

    BuildVariableResolver resolver = new BuildVariableResolver(project, computer);
    assertEquals("Variable resolution was incorrect", "ThisIsAJob", resolver.resolve("JOB_NAME"));
    verifyZeroInteractions(computer);
  }
  /*
   * Determine the Hudson parameter values from the OSLC parameter instances
   * in the AutomationRequest
   */
  private List<ParameterValue> getParameterValues(
      AbstractProject<?, ?> project, ParameterInstance[] parameters) {
    ParametersDefinitionProperty pp = project.getProperty(ParametersDefinitionProperty.class);
    if (pp == null) {
      LOG.log(Level.FINE, "Job does not take parameters: " + project.getName());
      throw HttpResponses.status(
          HttpServletResponse.SC_BAD_REQUEST); // This build is not parameterized.
    }

    HashMap<String, String> inputMap = new HashMap<String, String>();
    for (ParameterInstance param : parameters) {
      inputMap.put(param.getName(), param.getValue());
    }

    List<ParameterValue> values = new ArrayList<ParameterValue>();
    for (ParameterDefinition def : pp.getParameterDefinitions()) {
      String inputValue = inputMap.get(def.getName());
      if (inputValue == null) {
        ParameterValue defaultValue = def.getDefaultParameterValue();
        if (defaultValue == null) {
          LOG.log(
              Level.FINE, "Missing parameter " + def.getName() + " for job " + project.getName());
          throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
        }

        values.add(defaultValue);
      } else {
        if (def instanceof SimpleParameterDefinition) {
          SimpleParameterDefinition simple = (SimpleParameterDefinition) def;
          values.add(simple.createValue(inputValue));
        } else {
          LOG.log(
              Level.WARNING,
              "Unsupported parameter type with name "
                  + def.getName()
                  + " for project "
                  + project.getName());
          throw HttpResponses.status(HttpServletResponse.SC_NOT_IMPLEMENTED);
        }
      }
    }

    return values;
  }
 @Override
 public Collection<? extends Action> createFor(AbstractProject target) {
   try {
     ArrayList<abbrResult> results =
         readTestsFile(StabilityTestDataPublisher.getFilePath("Run"), target.getName());
     return Collections.singleton(new AllTestsHistoriesAction(results, target));
   } catch (IOException e) {
     return Collections.singleton(new AllTestsHistoriesAction(target));
   }
 }
Пример #9
0
  /**
   * Actually build a project, passing in parameters where appropriate
   *
   * @param project
   * @return
   */
  protected final boolean performBuildProject(AbstractProject<?, ?> project) {
    if (!project.hasPermission(AbstractProject.BUILD)) {
      LOGGER.log(Level.WARNING, "Insufficient permission to build job '" + project.getName() + "'");
      return false;
    }

    if (action.equals(BuildAction.POLL_SCM)) {
      project.schedulePolling();
      return true;
    }

    // no user parameters provided, just build it
    if (param == null) {
      project.scheduleBuild(new Cause.UserIdCause());
      return true;
    }

    ParametersDefinitionProperty pp =
        (ParametersDefinitionProperty) project.getProperty(ParametersDefinitionProperty.class);

    // project does not except any parameters, just build it
    if (pp == null) {
      project.scheduleBuild(new Cause.UserIdCause());
      return true;
    }

    List<ParameterDefinition> parameterDefinitions = pp.getParameterDefinitions();
    List<ParameterValue> values = new ArrayList<ParameterValue>();

    for (ParameterDefinition paramDef : parameterDefinitions) {

      if (!(paramDef instanceof StringParameterDefinition)) {
        // TODO add support for other parameter types
        values.add(paramDef.getDefaultParameterValue());
        continue;
      }

      StringParameterDefinition stringParamDef = (StringParameterDefinition) paramDef;
      ParameterValue value;

      // Did user supply this parameter?
      if (param.containsKey(paramDef.getName())) {
        value = stringParamDef.createValue(param.get(stringParamDef.getName()));
      } else {
        // No, then use the default value
        value = stringParamDef.createValue(stringParamDef.getDefaultValue());
      }

      values.add(value);
    }

    Jenkins.getInstance().getQueue().schedule(pp.getOwner(), 1, new ParametersAction(values));
    return true;
  }
Пример #10
0
 public JoinAction(
     JoinTrigger joinTrigger, BuildTrigger buildTrigger, ArrayList<String> otherDownstream) {
   this.pendingDownstreamProjects = new LinkedList<String>();
   if (buildTrigger != null) {
     for (AbstractProject project : buildTrigger.getChildProjects()) {
       if (!project.isDisabled()) {
         this.pendingDownstreamProjects.add(project.getName());
       }
     }
   }
   for (String proj : otherDownstream) {
     this.pendingDownstreamProjects.add(proj.trim());
   }
   this.joinProjects = joinTrigger.getJoinProjectsValue();
   this.joinPublishers = joinTrigger.getJoinPublishers();
   this.evenIfDownstreamUnstable = joinTrigger.getEvenIfDownstreamUnstable();
   this.completedDownstreamProjects = new LinkedList<String>();
   this.consideredBuilds = new LinkedList<String>();
   this.overallResult = Result.SUCCESS;
 }
Пример #11
0
  public synchronized void checkPendingDownstream(
      AbstractBuild<?, ?> owner, TaskListener listener) {
    if (pendingDownstreamProjects.isEmpty()) {
      listener.getLogger().println("All downstream projects complete!");
      Result threshold = this.evenIfDownstreamUnstable ? Result.UNSTABLE : Result.SUCCESS;
      if (this.overallResult.isWorseThan(threshold)) {
        listener.getLogger().println("Minimum result threshold not met for join project");
      } else {
        // Construct a launcher since CopyArchiver wants to get the
        // channel from it. We use the channel of the node where the
        // splitProject was built on.
        final Launcher launcher = new NoopLauncher(listener, owner);

        for (Publisher pub : this.joinPublishers) {
          try {
            pub.perform(owner, launcher, (BuildListener) listener);
          } catch (InterruptedException e) {
            e.printStackTrace();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
        if (!JoinTrigger.canDeclare(owner.getProject())) {
          List<AbstractProject> projects = Items.fromNameList(joinProjects, AbstractProject.class);
          for (AbstractProject project : projects) {
            listener.getLogger().println("Scheduling join project: " + project.getName());
            project.scheduleBuild(new JoinCause(owner));
          }
        }
      }
    } else {
      listener
          .getLogger()
          .println(
              "Project "
                  + owner.getProject().getName()
                  + " still waiting for "
                  + pendingDownstreamProjects.size()
                  + " builds to complete");
    }
  }
  @Override
  public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener)
      throws InterruptedException {
    listener.getLogger().println("[htmlpublisher] Archiving HTML reports...");

    // Grab the contents of the header and footer as arrays
    ArrayList<String> headerLines;
    ArrayList<String> footerLines;
    try {
      headerLines = this.readFile("/htmlpublisher/HtmlPublisher/header.html");
      footerLines = this.readFile("/htmlpublisher/HtmlPublisher/footer.html");
    } catch (FileNotFoundException e1) {
      e1.printStackTrace();
      return false;
    } catch (IOException e1) {
      e1.printStackTrace();
      return false;
    }

    for (int i = 0; i < this.reportTargets.size(); i++) {
      // Create an array of lines we will eventually write out, initially the header.
      ArrayList<String> reportLines = new ArrayList<String>(headerLines);
      HtmlPublisherTarget reportTarget = this.reportTargets.get(i);
      boolean keepAll = reportTarget.getKeepAll();

      FilePath archiveDir =
          build
              .getWorkspace()
              .child(resolveParametersInString(build, listener, reportTarget.getReportDir()));
      FilePath targetDir = reportTarget.getArchiveTarget(build);

      String levelString = keepAll ? "BUILD" : "PROJECT";
      listener
          .getLogger()
          .println(
              "[htmlpublisher] Archiving at "
                  + levelString
                  + " level "
                  + archiveDir
                  + " to "
                  + targetDir);

      // The index name might be a comma separated list of names, so let's figure out all the pages
      // we should index.
      String[] csvReports =
          resolveParametersInString(build, listener, reportTarget.getReportFiles()).split(",");
      ArrayList<String> reports = new ArrayList<String>();
      for (int j = 0; j < csvReports.length; j++) {
        String report = csvReports[j];
        report = report.trim();

        // Ignore blank report names caused by trailing or double commas.
        if (report.equals("")) {
          continue;
        }

        reports.add(report);
        String tabNo = "tab" + (j + 1);
        // Make the report name the filename without the extension.
        int end = report.lastIndexOf(".");
        String reportName;
        if (end > 0) {
          reportName = report.substring(0, end);
        } else {
          reportName = report;
        }
        String tabItem =
            "<li id=\""
                + tabNo
                + "\" class=\"unselected\" onclick=\"updateBody('"
                + tabNo
                + "');\" value=\""
                + report
                + "\">"
                + reportName
                + "</li>";
        reportLines.add(tabItem);
      }
      // Add the JS to change the link as appropriate.
      String hudsonUrl = Hudson.getInstance().getRootUrl();
      AbstractProject job = build.getProject();
      reportLines.add(
          "<script type=\"text/javascript\">document.getElementById(\"hudson_link\").innerHTML=\"Back to "
              + job.getName()
              + "\";</script>");
      // If the URL isn't configured in Hudson, the best we can do is attempt to go Back.
      if (hudsonUrl == null) {
        reportLines.add(
            "<script type=\"text/javascript\">document.getElementById(\"hudson_link\").onclick = function() { history.go(-1); return false; };</script>");
      } else {
        String jobUrl = hudsonUrl + job.getUrl();
        reportLines.add(
            "<script type=\"text/javascript\">document.getElementById(\"hudson_link\").href=\""
                + jobUrl
                + "\";</script>");
      }

      reportLines.add(
          "<script type=\"text/javascript\">document.getElementById(\"zip_link\").href=\"*zip*/"
              + reportTarget.getSanitizedName()
              + ".zip\";</script>");

      try {
        if (!archiveDir.exists()) {
          listener.error("Specified HTML directory '" + archiveDir + "' does not exist.");
          build.setResult(Result.FAILURE);
          return true;
        } else if (!keepAll) {
          // We are only keeping one copy at the project level, so remove the old one.
          targetDir.deleteRecursive();
        }

        if (archiveDir.copyRecursiveTo("**/*", targetDir) == 0) {
          listener.error(
              "Directory '" + archiveDir + "' exists but failed copying to '" + targetDir + "'.");
          if (build.getResult().isBetterOrEqualTo(Result.UNSTABLE)) {
            // If the build failed, don't complain that there was no coverage.
            // The build probably didn't even get to the point where it produces coverage.
            listener.error("This is especially strange since your build otherwise succeeded.");
          }
          build.setResult(Result.FAILURE);
          return true;
        }
      } catch (IOException e) {
        Util.displayIOException(e, listener);
        e.printStackTrace(listener.fatalError("HTML Publisher failure"));
        build.setResult(Result.FAILURE);
        return true;
      }

      reportTarget.handleAction(build);

      // Now add the footer.
      reportLines.addAll(footerLines);
      // And write this as the index
      try {
        writeFile(reportLines, new File(targetDir.getRemote(), reportTarget.getWrapperName()));
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

    return true;
  }
 @Override
 public int compare(AbstractProject a, AbstractProject b) {
   return a.getName().compareToIgnoreCase(b.getName());
 }
Пример #14
0
  /** Uses generatedJobs as existing data, so call before updating generatedJobs. */
  private Set<String> updateTemplates(
      AbstractBuild<?, ?> build, BuildListener listener, Set<GeneratedJob> freshJobs)
      throws IOException {
    AbstractProject<?, ?> seedJob = build.getProject();

    Set<String> freshTemplates = getTemplates(freshJobs);
    Set<String> existingTemplates =
        getTemplates(extractGeneratedObjects(seedJob, GeneratedJobsAction.class));
    Set<String> newTemplates = Sets.difference(freshTemplates, existingTemplates);
    Set<String> removedTemplates = Sets.difference(existingTemplates, freshTemplates);

    logItems(listener, "Existing templates", existingTemplates);
    logItems(listener, "New templates", newTemplates);
    logItems(listener, "Unreferenced templates", removedTemplates);

    // Collect information about the templates we loaded
    final String seedJobName = seedJob.getName();
    DescriptorImpl descriptor = Jenkins.getInstance().getDescriptorByType(DescriptorImpl.class);
    boolean descriptorMutated = false;

    // Clean up
    for (String templateName : removedTemplates) {
      Collection<SeedReference> seedJobReferences =
          descriptor.getTemplateJobMap().get(templateName);
      Collection<SeedReference> matching =
          Collections2.filter(seedJobReferences, new SeedNamePredicate(seedJobName));
      if (!matching.isEmpty()) {
        seedJobReferences.removeAll(matching);
        descriptorMutated = true;
      }
    }

    // Ensure we have a reference
    for (String templateName : freshTemplates) {
      Collection<SeedReference> seedJobReferences =
          descriptor.getTemplateJobMap().get(templateName);
      Collection<SeedReference> matching =
          Collections2.filter(seedJobReferences, new SeedNamePredicate(seedJobName));

      AbstractProject templateProject =
          getLookupStrategy().getItem(seedJob, templateName, AbstractProject.class);
      final String digest =
          Util.getDigestOf(new FileInputStream(templateProject.getConfigFile().getFile()));

      if (matching.size() == 1) {
        // Just update digest
        SeedReference ref = Iterables.get(matching, 0);
        if (digest.equals(ref.getDigest())) {
          ref.setDigest(digest);
          descriptorMutated = true;
        }
      } else {
        if (matching.size() > 1) {
          // Not sure how there could be more one, throw it all away and start over
          seedJobReferences.removeAll(matching);
        }
        seedJobReferences.add(new SeedReference(templateName, seedJobName, digest));
        descriptorMutated = true;
      }
    }

    if (descriptorMutated) {
      descriptor.save();
    }
    return freshTemplates;
  }