未验证 提交 b0eee6d6 编写于 作者: J Jeff Thompson 提交者: GitHub

[JENKINS-60848] Improve RSS title wording + Add more RSS tests (#4442)

* Add more tests.

Also a little cleanup of RSS.
Fix the broken "All all ..." title and description.
Remove a long unused bit for never implemented trackback.

* Increase date time checks.

* Copy and paste error.
Co-Authored-By: NWadeck Follonier <Wadeck@users.noreply.github.com>

* Assert not empty.
Co-Authored-By: NWadeck Follonier <Wadeck@users.noreply.github.com>

* Add a bunch more tests and clarify title.

Add a number of more tests. Test the various places that RSS is used.
Improve title wording to something consistent and somewhat sensible.
Co-authored-by: NWadeck Follonier <Wadeck@users.noreply.github.com>
上级 53ee8fa7
......@@ -157,6 +157,7 @@ public class LogRecorderManager extends AbstractModelObject implements ModelObje
*/
/*package*/ static void doRss(StaplerRequest req, StaplerResponse rsp, List<LogRecord> logs) throws IOException, ServletException {
// filter log records based on the log level
String entryType = "all";
String level = req.getParameter("level");
if(level!=null) {
Level threshold = Level.parse(level);
......@@ -166,9 +167,10 @@ public class LogRecorderManager extends AbstractModelObject implements ModelObje
filtered.add(r);
}
logs = filtered;
entryType = level;
}
RSS.forwardToRss("Hudson log","", logs, new FeedAdapter<LogRecord>() {
RSS.forwardToRss("Jenkins:log (" + entryType + " entries)","", logs, new FeedAdapter<LogRecord>() {
public String getEntryTitle(LogRecord entry) {
return entry.getMessage();
}
......
......@@ -1371,12 +1371,12 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
//
@Restricted(DoNotUse.class)
public void doRssAll( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
RSS.rss(req, rsp, getDisplayName() + " all builds", getUrl(), getBuilds());
RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds());
}
@Restricted(DoNotUse.class)
public void doRssFailed(StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
RSS.rss(req, rsp, getDisplayName() + " failed builds", getUrl(), getBuilds().failureOnly());
RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().failureOnly());
}
/**
......@@ -1398,7 +1398,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
}
}
}
RSS.rss(req, rsp, getDisplayName() + " last builds only", getUrl(), RunList.fromRuns(lastBuilds));
RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (latest builds)", getUrl(), RunList.fromRuns(lastBuilds));
}
@RequirePOST
......
......@@ -1566,12 +1566,12 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
public void doRssAll(StaplerRequest req, StaplerResponse rsp)
throws IOException, ServletException {
RSS.rss(req, rsp, getDisplayName() + " all builds", getUrl(), getBuilds().newBuilds());
RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds().newBuilds());
}
public void doRssFailed(StaplerRequest req, StaplerResponse rsp)
throws IOException, ServletException {
RSS.rss(req, rsp, getDisplayName() + " failed builds", getUrl(), getBuilds().failureOnly().newBuilds());
RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().failureOnly().newBuilds());
}
/**
......
......@@ -32,7 +32,6 @@ import org.kohsuke.stapler.StaplerResponse;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
/**
......@@ -42,25 +41,6 @@ import java.util.Collection;
*/
public final class RSS {
/**
* Parses trackback ping.
*/
public static void doTrackback( Object it, StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
String url = req.getParameter("url");
rsp.setStatus(HttpServletResponse.SC_OK);
rsp.setContentType("application/xml; charset=UTF-8");
try (PrintWriter pw = rsp.getWriter()) {
pw.println("<response>");
pw.println("<error>" + (url != null ? 0 : 1) + "</error>");
if (url == null) {
pw.println("<message>url must be specified</message>");
}
pw.println("</response>");
}
}
/**
* Sends the RSS feed to the client.
*
......
......@@ -871,11 +871,11 @@ public class User extends AbstractModelObject implements AccessControlled, Descr
}
public void doRssAll(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
RSS.rss(req, rsp, getDisplayName() + " all builds", getUrl(), getBuilds().newBuilds());
RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds().newBuilds());
}
public void doRssFailed(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
RSS.rss(req, rsp, getDisplayName() + " regression builds", getUrl(), getBuilds().regressionOnly());
RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().regressionOnly());
}
public void doRssLatest(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
......@@ -891,7 +891,7 @@ public class User extends AbstractModelObject implements AccessControlled, Descr
// historically these have been reported sorted by project name, we switched to the lazy iteration
// so we only have to sort the sublist of runs rather than the full list of irrelevant projects
lastBuilds.sort((o1, o2) -> Items.BY_FULL_NAME.compare(o1.getParent(), o2.getParent()));
RSS.rss(req, rsp, getDisplayName() + " latest build", getUrl(), RunList.fromRuns(lastBuilds), Run.FEED_ADAPTER_LATEST);
RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (latest builds)", getUrl(), RunList.fromRuns(lastBuilds), Run.FEED_ADAPTER_LATEST);
}
@Override
......
......@@ -1143,11 +1143,11 @@ public abstract class View extends AbstractModelObject implements AccessControll
}
public void doRssAll( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
RSS.rss(req, rsp, getDisplayName() + " all builds", getUrl(), getBuilds().newBuilds());
RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds().newBuilds());
}
public void doRssFailed( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
RSS.rss(req, rsp, getDisplayName() + " failed builds", getUrl(), getBuilds().failureOnly().newBuilds());
RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().failureOnly().newBuilds());
}
public RunList getBuilds() {
......@@ -1167,7 +1167,7 @@ public abstract class View extends AbstractModelObject implements AccessControll
if(lb!=null) lastBuilds.add(lb);
}
}
RSS.rss(req, rsp, getDisplayName() + " last builds only", getUrl(), RunList.fromRuns(lastBuilds), Run.FEED_ADAPTER_LATEST);
RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (latest builds)", getUrl(), RunList.fromRuns(lastBuilds), Run.FEED_ADAPTER_LATEST);
}
/**
......
......@@ -24,68 +24,134 @@
package hudson.model;
import com.gargoylesoftware.htmlunit.xml.XmlPage;
import jenkins.model.Jenkins;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.FailureBuilder;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.MockAuthorizationStrategy;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
public class RSSTest {
private static final String ROOT_PATH_PREFIX = "";
private static final String FAILED_BUILD_TITLE = "test0 #1 (broken since this build)";
private static final String STABLE_BUILD_TITLE = "test0 #1 (stable)";
private static final String ALL_BUILD_TYPE = "all";
private static final String FAILED_BUILD_TYPE = "failed";
private static final String LATEST_BUILD_TYPE = "latest";
@Rule
public JenkinsRule j = new JenkinsRule();
@Test
@Issue("JENKINS-59167")
public void absoluteURLsPresentInRSS_evenWithoutRootUrlSetup() throws Exception {
XmlPage page = getRssAllPage();
public void absoluteURLsPresentInRSS_evenWithoutRootUrlSetup_View() throws Exception {
String pathPrefix = ROOT_PATH_PREFIX;
XmlPage page = getRssAllPage(pathPrefix);
NodeList allLinks = page.getXmlDocument().getElementsByTagName("link");
assertEquals(1, allLinks.getLength());
assertAllRSSLinksContainRootUrl(allLinks);
FreeStyleProject p = j.createFreeStyleProject();
j.assertBuildStatusSuccess(p.scheduleBuild2(0));
runSuccessfulBuild();
page = getRssAllPage();
page = getRssAllPage(pathPrefix);
allLinks = page.getXmlDocument().getElementsByTagName("link");
assertEquals(2, allLinks.getLength());
assertAllRSSLinksContainRootUrl(allLinks);
}
private XmlPage getRssAllPage() throws Exception {
return (XmlPage) j.createWebClient().goTo("rssAll?flavor=rss20", "text/xml");
@Test
public void checkInitialContent_Rss_All_AllView() throws Exception {
String pathPrefix = ROOT_PATH_PREFIX;
int expectedNodes = 3;
XmlPage page = getRssAllPage(pathPrefix);
Node channelNode = checkRssWrapperNodes(page.getXmlDocument());
checkRssBasicNodes(channelNode, "Jenkins:All (all builds)", expectedNodes, pathPrefix);
}
private void assertAllRSSLinksContainRootUrl(NodeList allLinks) throws Exception {
for (int i = 0; i < allLinks.getLength(); i++) {
Node item = allLinks.item(i);
String url = item.getTextContent();
assertThat(url, containsString(j.getURL().toString()));
}
@Test
public void checkInitialContent_Rss_Failed_AllView() throws Exception {
String pathPrefix = ROOT_PATH_PREFIX;
int expectedNodes = 3;
XmlPage page = getRssFailedPage(pathPrefix);
Node channelNode = checkRssWrapperNodes(page.getXmlDocument());
checkRssBasicNodes(channelNode, "Jenkins:All (failed builds)", expectedNodes, pathPrefix);
}
@Test
public void checkInitialContent_Atom_All_AllView() throws Exception {
int expectedNodes = 5;
XmlPage page = getRssAllAtomPage();
Element documentElement = page.getXmlDocument().getDocumentElement();
assertThat(documentElement.getNodeName(), is("feed"));
checkAtomBasicNodes(documentElement, "Jenkins:All (all builds)", expectedNodes);
}
@Test
public void checkWithSingleBuild_Rss_All_AllView() throws Exception {
runSuccessfulBuild();
String pathPrefix = ROOT_PATH_PREFIX;
String displayName = "All";
String buildType = ALL_BUILD_TYPE;
String buildTitle = STABLE_BUILD_TITLE;
XmlPage page = getRssAllPage(pathPrefix);
checkSingleBuild_Rss(page, pathPrefix, displayName, buildType, buildTitle);
}
@Test
public void checkWithSingleBuild_Rss_Failed_AllView() throws Exception {
runFailingBuild();
String pathPrefix = ROOT_PATH_PREFIX;
String displayName = "All";
String buildType = FAILED_BUILD_TYPE;
String buildTitle = FAILED_BUILD_TITLE;
XmlPage page = getRssFailedPage(pathPrefix);
checkSingleBuild_Rss(page, pathPrefix, displayName, buildType, buildTitle);
}
@Test
public void checkWithSingleBuild_Atom_All_AllView() throws Exception {
runSuccessfulBuild();
String displayName = "All";
String buildType = ALL_BUILD_TYPE;
String buildTitle = STABLE_BUILD_TITLE;
XmlPage page = getRssAllAtomPage();
checkSingleBuild_Atom(page, displayName, buildType, buildTitle);
}
@Test
@Issue("JENKINS-59167")
public void absoluteURLsPresentInAtom_evenWithoutRootUrlSetup() throws Exception {
public void absoluteURLsPresentInAtom_evenWithoutRootUrlSetup_View() throws Exception {
XmlPage page = getRssAllAtomPage();
NodeList allLinks = page.getXmlDocument().getElementsByTagName("link");
assertEquals(1, allLinks.getLength());
assertAllAtomLinksContainRootUrl(allLinks);
FreeStyleProject p = j.createFreeStyleProject();
j.assertBuildStatusSuccess(p.scheduleBuild2(0));
runSuccessfulBuild();
page = getRssAllAtomPage();
allLinks = page.getXmlDocument().getElementsByTagName("link");
......@@ -94,6 +160,284 @@ public class RSSTest {
assertAllAtomLinksContainRootUrl(allLinks);
}
@Issue("JENKINS-60577")
@Test
public void latestBuilds_AllView() throws Exception {
String pathPrefix = ROOT_PATH_PREFIX;
String displayName = "All";
String buildType = LATEST_BUILD_TYPE;
int expectedLinks = 3;
int expectedAllLinks = 6;
checkLatestBuilds(j.createWebClient(), pathPrefix, displayName, buildType, null, expectedLinks, expectedAllLinks);
}
@Test
public void checkWithSingleBuild_Rss_All_Computer() throws Exception {
runSuccessfulBuild();
String pathPrefix = "computer/(master)/";
String displayName = "master";
String buildType = ALL_BUILD_TYPE;
String buildTitle = STABLE_BUILD_TITLE;
XmlPage page = getRssAllPage(pathPrefix);
checkSingleBuild_Rss(page, pathPrefix, displayName, buildType, buildTitle);
}
@Test
public void checkWithSingleBuild_Rss_Failed_Computer() throws Exception {
runFailingBuild();
String pathPrefix = "computer/(master)/";
String displayName = "master";
String buildType = FAILED_BUILD_TYPE;
String buildTitle = FAILED_BUILD_TITLE;
XmlPage page = getRssFailedPage(pathPrefix);
checkSingleBuild_Rss(page, pathPrefix, displayName, buildType, buildTitle);
}
@Test
public void latestBuilds_Computer() throws Exception {
String pathPrefix = "computer/(master)/";
String displayName = "master";
String buildType = LATEST_BUILD_TYPE;
int expectedLinks = 3;
int expectedAllLinks = 6;
checkLatestBuilds(j.createWebClient(), pathPrefix, displayName, buildType, null, expectedLinks, expectedAllLinks);
}
@Test
public void checkWithSingleBuild_Rss_All_Job() throws Exception {
runSuccessfulBuild();
String pathPrefix = "job/test0/";
String displayName = "test0";
String buildType = ALL_BUILD_TYPE;
String buildTitle = STABLE_BUILD_TITLE;
XmlPage page = getRssAllPage(pathPrefix);
checkSingleBuild_Rss(page, pathPrefix, displayName, buildType, buildTitle);
}
@Test
public void checkWithSingleBuild_Rss_Failed_Job() throws Exception {
runFailingBuild();
String pathPrefix = "job/test0/";
String displayName = "test0";
String buildType = FAILED_BUILD_TYPE;
String buildTitle = FAILED_BUILD_TITLE;
XmlPage page = getRssFailedPage(pathPrefix);
checkSingleBuild_Rss(page, pathPrefix, displayName, buildType, buildTitle);
}
@Test
public void checkWithSingleBuild_Rss_All_NewView() throws Exception {
FreeStyleProject p = runSuccessfulBuild();
ListView newView = new ListView("newView");
j.jenkins.addView(newView);
newView.add(p);
String pathPrefix = "view/newView/";
String displayName = "newView";
String buildType = ALL_BUILD_TYPE;
String buildTitle = STABLE_BUILD_TITLE;
XmlPage page = getRssAllPage(pathPrefix);
checkSingleBuild_Rss(page, pathPrefix, displayName, buildType, buildTitle);
}
@Test
public void checkWithSingleBuild_Rss_All_User() throws Exception {
String userId = "alice";
JenkinsRule.WebClient wc = loginAsUser(userId);
runSuccessfulBuild(userId);
String pathPrefix = "user/alice";
String displayName = userId;
String buildType = ALL_BUILD_TYPE;
String buildTitle = STABLE_BUILD_TITLE;
XmlPage page = getRssAllPage(wc, pathPrefix);
checkSingleBuild_Rss(page, pathPrefix, displayName, buildType, buildTitle);
}
@Test
public void checkWithSingleBuild_Rss_Failed_User() throws Exception {
String userId = "alice";
JenkinsRule.WebClient wc = loginAsUser(userId);
runFailingBuild(userId);
String pathPrefix = "user/alice";
String displayName = userId;
String buildType = FAILED_BUILD_TYPE;
String buildTitle = FAILED_BUILD_TITLE;
XmlPage page = getRssFailedPage(wc, pathPrefix);
checkSingleBuild_Rss(page, pathPrefix, displayName, buildType, buildTitle);
}
@Test
public void latestBuilds_User() throws Exception {
String userId = "alice";
JenkinsRule.WebClient wc = loginAsUser(userId);
String pathPrefix = "user/alice";
String displayName = userId;
String buildType = LATEST_BUILD_TYPE;
int expectedLinks = 3;
int expectedAllLinks = 6;
checkLatestBuilds(wc, pathPrefix, displayName, buildType, userId, expectedLinks, expectedAllLinks);
}
@Test
public void latestBuilds_User_NotCaused() throws Exception {
String userId = "alice";
JenkinsRule.WebClient wc = loginAsUser(userId);
String pathPrefix = "user/alice";
String displayName = userId;
String buildType = LATEST_BUILD_TYPE;
int expectedLinks = 1;
int expectedAllLinks = 1;
checkLatestBuilds(wc, pathPrefix, displayName, buildType, null, expectedLinks, expectedAllLinks);
}
@Test
public void checkInitialContent_Atom_AllLog() throws Exception {
JenkinsRule.WebClient webClient = j.createWebClient();
XmlPage page = (XmlPage) webClient.goTo("log/rss", "application/atom+xml");
Document xmlDocument = page.getXmlDocument();
Element documentElement = xmlDocument.getDocumentElement();
assertThat(documentElement.getNodeName(), is("feed"));
int expectedNodes = 5;
checkAtomBasicNodes(documentElement, "Jenkins:log (all entries)", expectedNodes);
}
@Test
public void checkInitialContent_Atom_SevereLog() throws Exception {
JenkinsRule.WebClient webClient = j.createWebClient();
XmlPage page = (XmlPage) webClient.goTo("log/rss?level=SEVERE", "application/atom+xml");
Document xmlDocument = page.getXmlDocument();
Element documentElement = xmlDocument.getDocumentElement();
assertThat(documentElement.getNodeName(), is("feed"));
int expectedNodes = 5;
checkAtomBasicNodes(documentElement, "Jenkins:log (SEVERE entries)", expectedNodes);
}
@Test
public void checkInitialContent_Atom_WarningLog() throws Exception {
JenkinsRule.WebClient webClient = j.createWebClient();
XmlPage page = (XmlPage) webClient.goTo("log/rss?level=WARNING", "application/atom+xml");
Document xmlDocument = page.getXmlDocument();
Element documentElement = xmlDocument.getDocumentElement();
assertThat(documentElement.getNodeName(), is("feed"));
int expectedNodes = 5;
checkAtomBasicNodes(documentElement, "Jenkins:log (WARNING entries)", expectedNodes);
}
private JenkinsRule.WebClient loginAsUser(String userId) throws Exception {
j.jenkins.setSecurityRealm(j.createDummySecurityRealm());
j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy().grant(Jenkins.ADMINISTER).everywhere().to(userId));
User alice = User.getById(userId, true);
JenkinsRule.WebClient wc = j.createWebClient();
wc.login(alice.getId());
return wc;
}
private Node checkRssWrapperNodes(Document xmlDocument) {
Element documentElement = xmlDocument.getDocumentElement();
assertThat(documentElement.getNodeName(), is("rss"));
assertThat(documentElement.getAttribute("version"), is("2.0"));
assertThat(documentElement.getChildNodes().getLength(), is(1));
Node channelNode = documentElement.getFirstChild();
assertThat(channelNode.getNodeName(), is("channel"));
return channelNode;
}
private XmlPage getRssFailedPage(String pathPrefix) throws IOException, SAXException {
return getRssFailedPage(j.createWebClient(), pathPrefix);
}
private XmlPage getRssFailedPage(JenkinsRule.WebClient webClient, String pathPrefix) throws IOException, SAXException {
String prefix = computeAdjustedPathPrefix(pathPrefix);
return (XmlPage) webClient.goTo(prefix + "rssFailed?flavor=rss20", "text/xml");
}
private void checkRssBasicNodes(Node channelNode, String expectedTitle, int expectedNodes, String path) throws IOException {
assertThat(channelNode.getChildNodes().getLength(), is(expectedNodes));
assertThat(getSingleNode(channelNode, "link").getTextContent(), is(j.getURL().toString() + path));
assertThat(getSingleNode(channelNode, "description").getTextContent(), is(expectedTitle));
assertThat(getSingleNode(channelNode, "title").getTextContent(), is(expectedTitle));
}
private void checkAtomBasicNodes(Node feedNode, String expectedTitle, int expectedNodes) throws IOException {
if (expectedNodes >= 0) {
assertThat(feedNode.getChildNodes().getLength(), is(expectedNodes));
}
Node linkNode = getSingleNode(feedNode, "link");
assertThat(linkNode.getAttributes().getNamedItem("rel").getTextContent(), is("alternate"));
assertThat(linkNode.getAttributes().getNamedItem("type").getTextContent(), is("text/html"));
assertThat(linkNode.getAttributes().getNamedItem("href").getTextContent(), is(j.getURL().toString()));
assertNotNull(getSingleNode(feedNode, "updated"));
assertThat(getSingleNode(feedNode, "title").getTextContent(), is(expectedTitle));
Node authorNode = getSingleNode(feedNode, "author");
NodeList authorNodes = authorNode.getChildNodes();
assertThat(authorNodes.getLength(), is(1));
Node nameNode = authorNodes.item(0);
assertThat(nameNode.getTextContent(), is("Jenkins Server"));
Node idNode = getSingleNode(feedNode, "id");
assertFalse(idNode.getTextContent().isEmpty());
}
private Node getSingleNode(Node parentNode, String nodeName) {
Node childNode = null;
NodeList childNodes = parentNode.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
if (childNodes.item(i).getNodeName().equals(nodeName)) {
if (childNode == null) {
childNode = childNodes.item(i);
} else {
fail("Too many children.");
}
}
}
return childNode;
}
private void checkRssTimeNode(Node firstBuild, String nodeName) throws ParseException {
String pubDate = getSingleNode(firstBuild, nodeName).getTextContent();
assertThat(pubDate, not(emptyString()));
DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
Date date = formatter.parse(pubDate);
assertNotNull(date);
}
private void checkAtomTimeNode(Node firstBuild, String nodeName) {
String publishedString = getSingleNode(firstBuild, nodeName).getTextContent();
assertNotNull(publishedString);
assertThat(publishedString, is(not(emptyString())));
OffsetDateTime dateTime = OffsetDateTime.parse(publishedString);
assertNotNull(dateTime);
}
private XmlPage getRssAllPage(String pathPrefix) throws Exception {
return getRssAllPage(j.createWebClient(), pathPrefix);
}
private XmlPage getRssAllPage(JenkinsRule.WebClient webClient, String pathPrefix) throws Exception {
String prefix = computeAdjustedPathPrefix(pathPrefix);
return (XmlPage) webClient.goTo(prefix + "rssAll?flavor=rss20", "text/xml");
}
private String computeAdjustedPathPrefix(String pathPrefix) {
return pathPrefix.isEmpty() || pathPrefix.endsWith("/") ? pathPrefix : pathPrefix + "/";
}
private void assertAllRSSLinksContainRootUrl(NodeList allLinks) throws Exception {
for (int i = 0; i < allLinks.getLength(); i++) {
Node item = allLinks.item(i);
String url = item.getTextContent();
assertThat(url, containsString(j.getURL().toString()));
}
}
private XmlPage getRssAllAtomPage() throws Exception {
return (XmlPage) j.createWebClient().goTo("rssAll", "application/atom+xml");
}
......@@ -107,39 +451,36 @@ public class RSSTest {
}
}
@Issue("JENKINS-60577")
@Test
public void latestBuilds() throws Exception {
XmlPage page = getRssLatestPage();
NodeList allLinks = page.getXmlDocument().getElementsByTagName("link");
assertEquals(1, allLinks.getLength());
FreeStyleProject p = j.createFreeStyleProject("test1");
j.assertBuildStatusSuccess(p.scheduleBuild2(0));
j.assertBuildStatusSuccess(p.scheduleBuild2(0));
private XmlPage getRssLatestPage(JenkinsRule.WebClient webClient, String pathPrefix) throws Exception {
String prefix = computeAdjustedPathPrefix(pathPrefix);
return (XmlPage) webClient.goTo(prefix + "rssLatest?flavor=rss20", "text/xml");
}
p = j.createFreeStyleProject("test2");
j.assertBuildStatusSuccess(p.scheduleBuild2(0));
j.assertBuildStatusSuccess(p.scheduleBuild2(0));
private FreeStyleProject runSuccessfulBuild() throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
j.assertBuildStatusSuccess(p.scheduleBuild2(0));
return p;
}
page = getRssLatestPage();
allLinks = page.getXmlDocument().getElementsByTagName("link");
assertEquals(3, allLinks.getLength());
assertLatestRSSLinks(allLinks);
private FreeStyleProject runSuccessfulBuild(String userId) throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(userId)));
return p;
}
page = getRssAllPage();
allLinks = page.getXmlDocument().getElementsByTagName("link");
assertEquals(6, allLinks.getLength());
private void runFailingBuild() throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
p.getBuildersList().add(new FailureBuilder());
j.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0).get());
}
private XmlPage getRssLatestPage() throws Exception {
return (XmlPage) j.createWebClient().goTo("rssLatest?flavor=rss20", "text/xml");
private void runFailingBuild(String userId) throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
p.getBuildersList().add(new FailureBuilder());
j.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0, new Cause.UserIdCause(userId)).get());
}
private void assertLatestRSSLinks(NodeList allLinks) throws Exception {
private void assertLatestRSSLinks(NodeList allLinks, String path) throws Exception {
List<String> urls = new ArrayList<>(allLinks.getLength());
for (int i = 0; i < allLinks.getLength(); i++) {
Node item = allLinks.item(i);
......@@ -148,9 +489,76 @@ public class RSSTest {
}
assertThat(urls, containsInAnyOrder(
j.getURL().toString(),
j.getURL().toString() + path,
j.getURL().toString() + "job/test1/2/",
j.getURL().toString() + "job/test2/3/"
));
}
private void checkSingleBuild_Rss(XmlPage page, String pathPrefix, String displayName, String buildType, String buildTitle) throws Exception {
Document xmlDocument = page.getXmlDocument();
Node channelNode = checkRssWrapperNodes(xmlDocument);
checkRssBasicNodes(channelNode, "Jenkins:" + displayName + " (" + buildType + " builds)", 4, pathPrefix);
NodeList items = xmlDocument.getElementsByTagName("item");
assertThat(items.getLength(), is(1));
Node firstBuild = items.item(0);
assertThat(firstBuild.getChildNodes().getLength(), is(5));
assertThat(getSingleNode(firstBuild, "title").getTextContent(), is(buildTitle));
checkRssTimeNode(firstBuild, "pubDate");
assertNotNull(getSingleNode(firstBuild, "author").getTextContent());
Node guidNode = getSingleNode(firstBuild, "guid");
assertThat(guidNode.getAttributes().getNamedItem("isPermaLink").getTextContent(), is("false"));
assertNotNull(guidNode.getTextContent());
}
private void checkSingleBuild_Atom(XmlPage page, String displayName, String buildType, String buildTitle) throws IOException {
Document xmlDocument = page.getXmlDocument();
Element documentElement = xmlDocument.getDocumentElement();
assertThat(documentElement.getNodeName(), is("feed"));
checkAtomBasicNodes(documentElement, "Jenkins:" + displayName + " (" + buildType + " builds)", 6);
NodeList entries = xmlDocument.getElementsByTagName("entry");
assertThat(entries.getLength(), is(1));
Node firstBuild = entries.item(0);
assertThat(firstBuild.getChildNodes().getLength(), is(5));
assertThat(getSingleNode(firstBuild, "title").getTextContent(), is(buildTitle));
checkAtomTimeNode(firstBuild, "published");
checkAtomTimeNode(firstBuild, "updated");
assertNotNull(getSingleNode(firstBuild, "id").getTextContent());
Node linkNode = getSingleNode(firstBuild, "link");
assertThat(linkNode.getAttributes().getNamedItem("rel").getTextContent(), is("alternate"));
assertThat(linkNode.getAttributes().getNamedItem("type").getTextContent(), is("text/html"));
assertThat(linkNode.getAttributes().getNamedItem("href").getTextContent(), containsString(j.getURL().toString()));
}
private void checkLatestBuilds(JenkinsRule.WebClient webClient, String pathPrefix, String displayName, String buildType, String userId,
int expectedLatesLinks, int expectedAllLinks) throws Exception {
XmlPage page = getRssLatestPage(webClient, pathPrefix);
NodeList allLinks = page.getXmlDocument().getElementsByTagName("link");
assertEquals(1, allLinks.getLength());
Node channelNode = checkRssWrapperNodes(page.getXmlDocument());
checkRssBasicNodes(channelNode, "Jenkins:" + displayName + " (" + buildType + " builds)", 3, pathPrefix);
FreeStyleProject p = j.createFreeStyleProject("test1");
j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(userId)));
j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(userId)));
p = j.createFreeStyleProject("test2");
j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(userId)));
j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(userId)));
j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(userId)));
page = getRssLatestPage(webClient, pathPrefix);
allLinks = page.getXmlDocument().getElementsByTagName("link");
assertEquals(expectedLatesLinks, allLinks.getLength());
if (expectedLatesLinks > 1) {
assertLatestRSSLinks(allLinks, pathPrefix);
}
page = getRssAllPage(webClient, pathPrefix);
allLinks = page.getXmlDocument().getElementsByTagName("link");
assertEquals(expectedAllLinks, allLinks.getLength());
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册