diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml index 43d62816190d..a65d82e1b647 100644 --- a/.mvn/extensions.xml +++ b/.mvn/extensions.xml @@ -2,6 +2,6 @@ io.jenkins.tools.incrementals git-changelist-maven-extension - 1.2 + 1.3 diff --git a/bom/pom.xml b/bom/pom.xml index e6f01226dfad..2fe8f8bfd9b3 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -37,7 +37,6 @@ THE SOFTWARE. Jenkins BOM The module contains dependencies that are used by a specific Jenkins version - 9.2 1.7.32 @@ -47,7 +46,8 @@ THE SOFTWARE. - + + org.springframework.security spring-security-bom 5.6.1 @@ -119,10 +119,11 @@ THE SOFTWARE. ${slf4jVersion} + commons-logging commons-logging 1.2 - provided + provided org.slf4j @@ -130,10 +131,11 @@ THE SOFTWARE. ${slf4jVersion} + log4j log4j 1.2.17 - provided + provided org.samba.jcifs @@ -226,7 +228,8 @@ THE SOFTWARE. windows-package-checker 1.2 - + + args4j args4j 2.33 @@ -340,7 +343,8 @@ THE SOFTWARE. groovy-all ${groovy.version} - + + org.fusesource.jansi jansi 1.11 @@ -372,7 +376,7 @@ THE SOFTWARE. jenkins-stapler-support 1.1 - + org.kohsuke.stapler json-lib 2.4-jenkins-3 @@ -464,10 +468,10 @@ THE SOFTWARE. flatten - process-resources flatten + process-resources bom diff --git a/cli/pom.xml b/cli/pom.xml index 59a7354a8527..34a47850a8b2 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -130,10 +130,10 @@ 3.2.4 - package shade + package false @@ -187,10 +187,10 @@ add-source - generate-sources add-source + generate-sources ${project.build.directory}/generated-sources/localizer diff --git a/cli/src/main/java/hudson/cli/CLI.java b/cli/src/main/java/hudson/cli/CLI.java index 06baf6be13e6..862847df9673 100644 --- a/cli/src/main/java/hudson/cli/CLI.java +++ b/cli/src/main/java/hudson/cli/CLI.java @@ -115,7 +115,7 @@ public static int _main(String[] _args) throws Exception { if (url==null) url = System.getenv("HUDSON_URL"); - + boolean noKeyAuth = false; // TODO perhaps allow mode to be defined by environment variable too (assuming $JENKINS_USER_ID can be used for -user) @@ -189,9 +189,9 @@ public boolean verify(String s, SSLSession sslSession) { continue; } if (head.equals("-noKeyAuth")) { - noKeyAuth = true; - args = args.subList(1,args.size()); - continue; + noKeyAuth = true; + args = args.subList(1,args.size()); + continue; } if(head.equals("-i") && args.size()>=2) { File f = getFileFromArguments(args); diff --git a/cli/src/test/java/hudson/cli/PrivateKeyProviderTest.java b/cli/src/test/java/hudson/cli/PrivateKeyProviderTest.java index 9205c853f8ce..8d960e87a461 100644 --- a/cli/src/test/java/hudson/cli/PrivateKeyProviderTest.java +++ b/cli/src/test/java/hudson/cli/PrivateKeyProviderTest.java @@ -50,7 +50,7 @@ public void loadKeyDSAPassword() throws IOException, GeneralSecurityException { String password = "password"; assertKeyPairNotNull(file, password); } - + /** key command: ssh-keygen -f rsa -t rsa -b 1024 -m PEM */ @@ -69,7 +69,7 @@ public void loadKeyRSAPassword() throws IOException, GeneralSecurityException { String password = "password"; assertKeyPairNotNull(file, password); } - + /** key command: ssh-keygen -f openssh -t rsa -b 1024 */ @@ -78,7 +78,7 @@ public void loadKeyOpenSSH() throws IOException, GeneralSecurityException { File file = new File(this.getClass().getResource("openssh").getFile()); assertKeyPairNotNull(file, null); } - + /** key command: ssh-keygen -f openssh-unsupported -t rsa -b 1024 -m PKCS8 -p password */ @@ -123,7 +123,7 @@ public void loadBlankKey() throws IOException, GeneralSecurityException { /** key command: ssh-keygen -f openssh -t rsa -b 1024 in this key we remove some lines to break the key. - */ + */ @Test public void loadKeyBroken() throws IOException, GeneralSecurityException { File file = new File(this.getClass().getResource("openssh-broken").getFile()); diff --git a/core/pom.xml b/core/pom.xml index 48d4ea485f9b..0b10a40a0d22 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -56,7 +56,6 @@ THE SOFTWARE. - ${project.groupId} @@ -76,7 +75,8 @@ THE SOFTWARE. crypto-util - + + org.jenkins-ci core-annotation-processors 1.0 @@ -163,7 +163,8 @@ THE SOFTWARE. org.kohsuke.stapler stapler-adjunct-codemirror - + + org.kohsuke.stapler stapler-adjunct-timeline 1.5 @@ -193,7 +194,7 @@ THE SOFTWARE. ${bridge-method-injector.version} - + org.kohsuke.stapler json-lib @@ -266,7 +267,8 @@ THE SOFTWARE. commons-io commons-io - + + commons-lang commons-lang @@ -382,13 +384,15 @@ THE SOFTWARE. org.codehaus.groovy groovy-all - + + jline jline 2.14.6 compile - + + org.fusesource.jansi jansi @@ -427,7 +431,8 @@ THE SOFTWARE. ${mockito.version} test - + + jakarta.servlet.jsp.jstl jakarta.servlet.jsp.jstl-api @@ -483,7 +488,8 @@ THE SOFTWARE. org.kohsuke.jinterop j-interop - + + org.kohsuke.metainf-services metainf-services 1.8 @@ -583,10 +589,10 @@ THE SOFTWARE. add-source - generate-sources add-source + generate-sources ${project.build.directory}/generated-sources/antlr @@ -639,7 +645,8 @@ THE SOFTWARE. maven-stapler-plugin - ${staplerFork} + + ${staplerFork} 128m @@ -704,11 +711,11 @@ THE SOFTWARE. winsw - generate-resources copy + generate-resources @@ -733,7 +740,8 @@ THE SOFTWARE. false - + + maven-jar-plugin @@ -751,7 +759,8 @@ THE SOFTWARE. - + + org.kohsuke.stapler maven-stapler-plugin @@ -761,7 +770,8 @@ THE SOFTWARE. - + + maven-project-info-reports-plugin @@ -834,7 +844,8 @@ THE SOFTWARE. com.github.siom79.japicmp japicmp-maven-plugin - 0.14.4-20200728.214757-1 + + 0.14.4-20200728.214757-1 @@ -843,7 +854,8 @@ THE SOFTWARE. true - + + javax.servlet javax.servlet-api 3.1.0 @@ -853,10 +865,10 @@ THE SOFTWARE. - verify cmp + verify diff --git a/core/src/main/java/hudson/ClassicPluginStrategy.java b/core/src/main/java/hudson/ClassicPluginStrategy.java index ef29f481586b..46e2d7235fb5 100644 --- a/core/src/main/java/hudson/ClassicPluginStrategy.java +++ b/core/src/main/java/hudson/ClassicPluginStrategy.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Jean-Baptiste Quenot, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -121,7 +121,7 @@ private static boolean isLinked(File archive) { } private static Manifest loadLinkedManifest(File archive) throws IOException { - // resolve the .hpl file to the location of the manifest file + // resolve the .hpl file to the location of the manifest file try { // Locate the manifest String firstLine; @@ -137,7 +137,7 @@ private static Manifest loadLinkedManifest(File archive) throws IOException { // indirection archive = resolve(archive, firstLine); } - + // Read the manifest try (InputStream manifestInput = Files.newInputStream(archive.toPath())) { return new Manifest(manifestInput); @@ -232,7 +232,7 @@ private static Manifest loadLinkedManifest(File archive) throws IOException { } } } - + fix(atts,optionalDependencies); // Register global classpath mask. This is useful for hiding JavaEE APIs that you might see from the container, @@ -253,7 +253,7 @@ private static Manifest loadLinkedManifest(File archive) throws IOException { private void fix(Attributes atts, List optionalDependencies) { String pluginName = atts.getValue("Short-Name"); - + String jenkinsVersion = atts.getValue("Jenkins-Version"); if (jenkinsVersion==null) jenkinsVersion = atts.getValue("Hudson-Version"); @@ -430,7 +430,7 @@ private DependencyClassLoader findAncestorDependencyClassLoader(ClassLoader clas if (classLoader instanceof DependencyClassLoader) { return (DependencyClassLoader)classLoader; } - + if (classLoader instanceof AntClassLoader) { // AntClassLoaders hold parents not only as AntClassLoader#getParent() // but also as AntClassLoader#getConfiguredParent() diff --git a/core/src/main/java/hudson/CopyOnWrite.java b/core/src/main/java/hudson/CopyOnWrite.java index ff6bc92d5756..a36dbaf4e9f9 100644 --- a/core/src/main/java/hudson/CopyOnWrite.java +++ b/core/src/main/java/hudson/CopyOnWrite.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/hudson/ExtensionListListener.java b/core/src/main/java/hudson/ExtensionListListener.java index f5c8528add39..6a29da2d465d 100644 --- a/core/src/main/java/hudson/ExtensionListListener.java +++ b/core/src/main/java/hudson/ExtensionListListener.java @@ -35,7 +35,7 @@ public abstract class ExtensionListListener { * {@link ExtensionList} contents has changed. *

* This would be called when an entry gets added to or removed from the list for any reason e.g. - * when a dynamically loaded plugin introduces a new {@link ExtensionPoint} implementation + * when a dynamically loaded plugin introduces a new {@link ExtensionPoint} implementation * that adds an entry to the {@link ExtensionList} being listened to. */ public abstract void onChange(); diff --git a/core/src/main/java/hudson/ExtensionPoint.java b/core/src/main/java/hudson/ExtensionPoint.java index 73063ec8324d..426aa52b05a3 100644 --- a/core/src/main/java/hudson/ExtensionPoint.java +++ b/core/src/main/java/hudson/ExtensionPoint.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -51,7 +51,7 @@ public interface ExtensionPoint { /** * Used by designers of extension points (direct subtypes of {@link ExtensionPoint}) to indicate that * the legacy instances are scoped to {@link Jenkins} instance. By default, legacy instances are - * static scope. + * static scope. */ @Target(TYPE) @Retention(RUNTIME) diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index cadb8cc257e9..a3eb22406c32 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -1,20 +1,20 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Eric Lefevre-Ardant, Erik Ramfelt, Michael B. Donohue, Alan Harder, * Manufacture Francaise des Pneumatiques Michelin, Romain Seguy - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -198,7 +198,7 @@ *

* When {@link FileCallable} is transferred to a remote node, it will be done so * by using the same Java serialization scheme that the remoting module uses. - * See {@link Channel} for more about this. + * See {@link Channel} for more about this. * *

* {@link FilePath} itself can be sent over to a remote node as a part of {@link Callable} @@ -229,7 +229,7 @@ public final class FilePath implements SerializableOnlyOverRemoting { * This is used to determine whether we are running on the controller / the built-in node, or an agent. */ private transient VirtualChannel channel; - + /** * Represent the path to the file in the controller or the agent * Since the platform of the agent might be different, can't use java.io.File @@ -369,7 +369,7 @@ boolean isUnix() { // if the path represents a local path, there' no need to guess. if(!isRemote()) return File.pathSeparatorChar!=';'; - + // note that we can't use the usual File.pathSeparator and etc., as the OS of // the machine where this code runs and the OS that this FilePath refers to may be different. @@ -411,7 +411,7 @@ public void zip(FilePath dst) throws IOException, InterruptedException { zip(os); } } - + /** * Creates a zip file from this directory by using the specified filter, * and sends the result to the given output stream. @@ -808,7 +808,7 @@ public Void invoke(File f, VirtualChannel channel) throws IOException, Interrupt return null; } } - + /** * Resolves symlink, if the given file is a symlink. Otherwise return null. *

@@ -843,7 +843,7 @@ public boolean equals(Object o) { public int hashCode() { return 31 * (channel != null ? channel.hashCode() : 0) + remote.hashCode(); } - + /** * Supported tar file compression methods. */ @@ -1083,7 +1083,7 @@ public void copyFrom(InputStream in) throws IOException, InterruptedException { /** * Convenience method to call {@link FilePath#copyTo(FilePath)}. - * + * * @since 1.311 */ public void copyFrom(FilePath src) throws IOException, InterruptedException { @@ -1345,7 +1345,7 @@ public Boolean invoke(File f, VirtualChannel channel) throws IOException, Interr return mkdirs(f) || f.exists(); } } - + /** * Deletes all suffixes recursively. * @throws IOException if it exists but could not be successfully deleted @@ -1368,7 +1368,7 @@ public Void invoke(File f, VirtualChannel channel) throws IOException { Util.deleteRecursive(file.toPath(), path -> path.toFile()); } } - + return null; } } @@ -1734,7 +1734,7 @@ public Void invoke(File f, VirtualChannel channel) throws IOException { return null; } } - + private void setLastModifiedIfPossible(final long timestamp) throws IOException, InterruptedException { String message = act(new SetLastModified(timestamp)); @@ -1776,7 +1776,7 @@ public Boolean invoke(File f, VirtualChannel channel) throws IOException { return f.isDirectory(); } } - + /** * Returns the file size in bytes. * @@ -2242,18 +2242,18 @@ public int read(byte[] b) throws IOException { actAsync(new OffsetPipeSecureFileCallable(p, offset)); return new java.util.zip.GZIPInputStream(p.getIn()); } - + private static class OffsetPipeSecureFileCallable extends MasterToSlaveFileCallable { private static final long serialVersionUID = 1L; - + private Pipe p; private long offset; - + private OffsetPipeSecureFileCallable(Pipe p, long offset) { this.p = p; this.offset = offset; } - + @Override public Void invoke(File f, VirtualChannel channel) throws IOException { try (OutputStream os = p.getOut(); @@ -2275,9 +2275,9 @@ public Void invoke(File f, VirtualChannel channel) throws IOException { */ public String readToString() throws IOException, InterruptedException { return act(new ReadToString()); - } + } private static class ReadToString extends MasterToSlaveFileCallable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; @Override public String invoke(File f, VirtualChannel channel) throws IOException, InterruptedException { return new String(Files.readAllBytes(fileToPath(f)), Charset.defaultCharset()); @@ -2364,9 +2364,9 @@ public String invoke(File f, VirtualChannel channel) throws IOException { * be on the some host */ public void renameTo(final FilePath target) throws IOException, InterruptedException { - if(this.channel != target.channel) { - throw new IOException("renameTo target must be on the same host"); - } + if(this.channel != target.channel) { + throw new IOException("renameTo target must be on the same host"); + } act(new RenameTo(target)); } private static class RenameTo extends MasterToSlaveFileCallable { @@ -2536,10 +2536,10 @@ interface RemoteCopier { /** * Copies the contents of this directory recursively into the specified target directory. - * + * * @return * the number of files copied. - * @since 1.312 + * @since 1.312 */ public int copyRecursiveTo(FilePath target) throws IOException, InterruptedException { return copyRecursiveTo("**/*",target); @@ -2685,8 +2685,8 @@ public void visit(File f, String relativePath) throws IOException { if (exceptionEncountered) { Files.copy(fileToPath(f), targetPath, StandardCopyOption.REPLACE_EXISTING); if (!logMessageShown) { - LOGGER.log(Level.INFO, - "JENKINS-52325: Jenkins failed to retain attributes when copying to {0}, so proceeding without attributes.", + LOGGER.log(Level.INFO, + "JENKINS-52325: Jenkins failed to retain attributes when copying to {0}, so proceeding without attributes.", dest.getAbsolutePath()); logMessageShown = true; } @@ -2695,14 +2695,14 @@ public void visit(File f, String relativePath) throws IOException { } } private boolean tryCopyWithAttributes(File f, Path targetPath) { - try { + try { Files.copy(fileToPath(f), targetPath, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { LOGGER.log(Level.FINE, "Unable to copy: {0}", e.getMessage()); return false; } - return true; + return true; } @Override public boolean understandsSymlink() { @@ -2958,7 +2958,7 @@ public String invoke(File dir, VirtualChannel channel) throws IOException, Inter final String fileMask = tokens.nextToken().trim(); if(hasMatch(dir,fileMask,caseSensitive)) continue; // no error on this portion - + // JENKINS-5253 - if we can get some match in case insensitive mode // and user requested case sensitive match, notify the user if (caseSensitive && hasMatch(dir, fileMask, false)) { @@ -3126,7 +3126,7 @@ private UrlFactory getUrlFactory() { public static FormValidation validateFileMask(@CheckForNull FilePath path, String value) throws IOException { return FilePath.validateFileMask(path, value, true); } - + /** * Shortcut for {@link #validateFileMask(String,boolean,boolean)} with {@code errorIfNotExist} true, as the left-hand side can be null. */ @@ -3136,14 +3136,14 @@ public static FormValidation validateFileMask(@CheckForNull FilePath path, Strin } /** - * Short for {@code validateFileMask(value, true, true)} + * Short for {@code validateFileMask(value, true, true)} */ public FormValidation validateFileMask(String value) throws IOException { return validateFileMask(value, true, true); } - + /** - * Short for {@code validateFileMask(value, errorIfNotExist, true)} + * Short for {@code validateFileMask(value, errorIfNotExist, true)} */ public FormValidation validateFileMask(String value, boolean errorIfNotExist) throws IOException { return validateFileMask(value, errorIfNotExist, true); @@ -3226,7 +3226,7 @@ public FormValidation validateRelativePath(String value, boolean errorIfNotExist } } - String msg = expectingFile ? Messages.FilePath_validateRelativePath_noSuchFile(value) : + String msg = expectingFile ? Messages.FilePath_validateRelativePath_noSuchFile(value) : Messages.FilePath_validateRelativePath_noSuchDirectory(value); if(errorIfNotExist) return FormValidation.error(msg); else return FormValidation.warning(msg); @@ -3266,7 +3266,7 @@ public VirtualChannel getChannel() { } /** - * Returns true if this {@link FilePath} represents a remote file. + * Returns true if this {@link FilePath} represents a remote file. */ public boolean isRemote() { return channel!=null; @@ -3308,8 +3308,9 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound private static final long serialVersionUID = 1L; - @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "TODO needs triage") - public static int SIDE_BUFFER_SIZE = 1024; + @Restricted(NoExternalUse.class) + @RestrictedSince("TODO") + public static final int SIDE_BUFFER_SIZE = 1024; private static final Logger LOGGER = Logger.getLogger(FilePath.class.getName()); @@ -3424,7 +3425,7 @@ public ExplicitlySpecifiedDirScanner(Map files) { new NamingThreadFactory(new DaemonThreadFactory(), "FilePath.localPool")) )); - + /** * Channel to the current instance. */ @@ -3490,7 +3491,7 @@ public Boolean invoke(@NonNull File parentFile, @NonNull VirtualChannel channel) if (new File(potentialChildRelativePath).isAbsolute()) { throw new IllegalArgumentException("Only a relative path is supported, the given path is absolute: " + potentialChildRelativePath); } - + Path parentAbsolutePath = Util.fileToPath(parentFile.getAbsoluteFile()); Path parentRealPath; try { @@ -3538,7 +3539,7 @@ public Boolean invoke(@NonNull File parentFile, @NonNull VirtualChannel channel) } } catch (NoSuchFileException e) { // nonexistent file / Windows Server 2016 + MSFT docker - // in case this folder / file will be copied somewhere else, + // in case this folder / file will be copied somewhere else, // it becomes the responsibility of that system to check the isDescendant with the existing links // we are not taking the parentRealPath to avoid possible problem Path child = currentFileAbsolutePath.normalize(); @@ -3560,7 +3561,7 @@ public Boolean invoke(@NonNull File parentFile, @NonNull VirtualChannel channel) } return current; } - + private @NonNull Path windowsToRealPath(@NonNull Path path) throws IOException { try { return path.toRealPath(); diff --git a/core/src/main/java/hudson/Launcher.java b/core/src/main/java/hudson/Launcher.java index 57de28f89d5e..5b67208c5c93 100644 --- a/core/src/main/java/hudson/Launcher.java +++ b/core/src/main/java/hudson/Launcher.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Stephen Connolly, CloudBees, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -85,7 +85,7 @@ * * * @author Kohsuke Kawaguchi - * @see FilePath#createLauncher(TaskListener) + * @see FilePath#createLauncher(TaskListener) */ public abstract class Launcher { @@ -146,7 +146,7 @@ public VirtualChannel getChannel() { /** * Gets the {@link TaskListener} that this launcher uses to * report the commands that it's executing. - * + * * @return Task listener */ @NonNull @@ -289,7 +289,7 @@ public boolean quiet() { /** * Sets the current directory. - * + * * @param workDir Work directory to be used. * If {@code null}, the default/current directory will be used by the process starter * @return {@code this} @@ -314,8 +314,8 @@ public FilePath pwd() { /** * Sets STDOUT destination. - * - * @param out Output stream. + * + * @param out Output stream. * Use {@code null} to send STDOUT to {@code /dev/null}. * @return {@code this} */ @@ -327,7 +327,7 @@ public ProcStarter stdout(@CheckForNull OutputStream out) { /** * Sends the stdout to the given {@link TaskListener}. - * + * * @param out Task listener (must be safely remotable) * @return {@code this} */ @@ -339,7 +339,7 @@ public ProcStarter stdout(@NonNull TaskListener out) { /** * Gets current STDOUT destination. - * + * * @return STDOUT output stream. {@code null} if STDOUT is suppressed or undefined. */ @CheckForNull @@ -358,7 +358,7 @@ public ProcStarter stderr(@CheckForNull OutputStream err) { /** * Gets current STDERR destination. - * + * * @return STDERR output stream. {@code null} if suppressed or undefined. */ @CheckForNull @@ -369,7 +369,7 @@ public OutputStream stderr() { /** * Controls where the stdin of the process comes from. * By default, {@code /dev/null}. - * + * * @return {@code this} */ @NonNull @@ -380,7 +380,7 @@ public ProcStarter stdin(@CheckForNull InputStream in) { /** * Gets current STDIN destination. - * + * * @return STDIN output stream. {@code null} if suppressed or undefined. */ @CheckForNull @@ -395,7 +395,7 @@ public InputStream stdin() { * In addition to what the current process * is inherited (if this is going to be launched from a agent agent, that * becomes the "current" process), these variables will be also set. - * + * * @param overrides Environment variables to be overridden * @return {@code this} */ @@ -407,7 +407,7 @@ public ProcStarter envs(@NonNull Map overrides) { /** * @param overrides * List of "VAR=VALUE". See {@link #envs(Map)} for the semantics. - * + * * @return {@code this} */ public ProcStarter envs(@CheckForNull String... overrides) { @@ -425,7 +425,7 @@ public ProcStarter envs(@CheckForNull String... overrides) { /** * Gets a list of environment variables to be set. * Returns an empty array if envs field has not been initialized. - * + * * @return If initialized, returns a copy of internal envs array. Otherwise - a new empty array. */ @NonNull @@ -470,7 +470,7 @@ public ProcStarter readStderr() { * Indicates that the caller will directly write to the child process {@link #stdin()} via {@link Proc#getStdin()}. * (Whereas by default you call {@link #stdin(InputStream)} * and let Jenkins pump your {@link InputStream} of choosing to stdin.) - * + * * @return {@code this} * @since 1.399 */ @@ -518,7 +518,7 @@ public int join() throws IOException, InterruptedException { // The logging around procHolderForJoin prevents the preliminary object deallocation we saw in JENKINS-23271 final Proc procHolderForJoin = start(); LOGGER.log(Level.FINER, "Started the process {0}", procHolderForJoin); - + if (procHolderForJoin instanceof ProcWithJenkins23271Patch) { return procHolderForJoin.join(); } else { @@ -762,7 +762,7 @@ public Proc launch(String[] cmd, boolean[] mask, String[] env, InputStream in, O *

* When the returned channel is terminated, the process will be killed. * - * @param cmd + * @param cmd * The commands. * @param out * Where the stderr from the launched process will be sent. @@ -774,7 +774,7 @@ public Proc launch(String[] cmd, boolean[] mask, String[] env, InputStream in, O * is inherited (if this is going to be launched from an agent, that * becomes the "current" process), these variables will be also set. */ - public abstract Channel launchChannel(@NonNull String[] cmd, @NonNull OutputStream out, + public abstract Channel launchChannel(@NonNull String[] cmd, @NonNull OutputStream out, @CheckForNull FilePath workDir, @NonNull Map envVars) throws IOException, InterruptedException; /** @@ -831,7 +831,7 @@ protected final void maskedPrintCommandLine(@NonNull List cmd, @CheckFor printCommandLine(cmd.toArray(new String[0]),workDir); return; } - + assert mask.length == cmd.size(); final String[] masked = new String[cmd.size()]; for (int i = 0; i < cmd.size(); i++) { @@ -843,14 +843,14 @@ protected final void maskedPrintCommandLine(@NonNull List cmd, @CheckFor } printCommandLine(masked, workDir); } - + protected final void maskedPrintCommandLine(@NonNull String[] cmd, @NonNull boolean[] mask, @CheckForNull FilePath workDir) { maskedPrintCommandLine(Arrays.asList(cmd),mask,workDir); } /** * Returns a decorated {@link Launcher} for the given node. - * + * * @param node Node for which this launcher is created. * @return Decorated instance of the Launcher. */ @@ -877,7 +877,7 @@ public final Launcher decorateByPrefix(final String... prefix) { public boolean isUnix() { return outer.isUnix(); } - + @Override public Proc launch(ProcStarter starter) throws IOException { starter.commands.addAll(0,Arrays.asList(prefix)); @@ -987,7 +987,7 @@ public Proc launch(ProcStarter ps) throws IOException { // replace variables in command line String[] jobCmd = new String[ps.commands.size()]; for ( int idx = 0 ; idx < jobCmd.length; idx++ ) - jobCmd[idx] = jobEnv.expand(ps.commands.get(idx)); + jobCmd[idx] = jobEnv.expand(ps.commands.get(idx)); return new LocalProc(jobCmd, Util.mapToEnv(jobEnv), ps.reverseStdin ?LocalProc.SELFPUMP_INPUT:ps.stdin, @@ -1111,7 +1111,7 @@ public Proc launch(ProcStarter ps) throws IOException { final OutputStream out = ps.stdout == null || ps.stdoutListener != null ? null : new RemoteOutputStream(new CloseProofOutputStream(ps.stdout)); final OutputStream err = ps.stderr==null ? null : new RemoteOutputStream(new CloseProofOutputStream(ps.stderr)); final InputStream in = ps.stdin == null || ps.stdin == NULL_INPUT_STREAM ? null : new RemoteInputStream(ps.stdin, false); - + final FilePath psPwd = ps.pwd; final String workDir = psPwd==null ? null : psPwd.getRemote(); @@ -1230,14 +1230,14 @@ public OutputStream getStdin() { } } } - + /** - * A launcher which delegates to a provided inner launcher. + * A launcher which delegates to a provided inner launcher. * Allows subclasses to only implement methods they want to override. - * Originally, this launcher has been implemented in + * Originally, this launcher has been implemented in * * Custom Tools Plugin. - * + * * @author rcampbell * @author Oleg Nenashev, Synopsys Inc. * @since 1.568 @@ -1301,9 +1301,9 @@ public VirtualChannel getChannel() { @Override public Proc launch(String[] cmd, String[] env, InputStream in, OutputStream out, FilePath workDir) throws IOException { - return inner.launch(cmd, env, in, out, workDir); + return inner.launch(cmd, env, in, out, workDir); } - + /** * Gets nested launcher. * @return Inner launcher @@ -1311,7 +1311,7 @@ public Proc launch(String[] cmd, String[] env, InputStream in, OutputStream out, @NonNull public Launcher getInner() { return inner; - } + } } public static class IOTriplet implements Serializable { @@ -1328,7 +1328,7 @@ public interface RemoteProcess { int join() throws InterruptedException, IOException; void kill() throws IOException, InterruptedException; boolean isAlive() throws IOException, InterruptedException; - + @NonNull IOTriplet getIOtriplet(); } @@ -1350,8 +1350,8 @@ private static class RemoteLaunchCallable extends MasterToSlaveCallable cmd, @CheckForNull boolean[] masks, @CheckForNull String[] env, @CheckForNull InputStream in, boolean reverseStdin, - @CheckForNull OutputStream out, boolean reverseStdout, - @CheckForNull OutputStream err, boolean reverseStderr, + @CheckForNull OutputStream out, boolean reverseStdout, + @CheckForNull OutputStream err, boolean reverseStderr, boolean quiet, @CheckForNull String workDir, @NonNull TaskListener listener, @CheckForNull TaskListener stdoutListener) { this.cmd = new ArrayList<>(cmd); this.masks = masks; @@ -1448,7 +1448,7 @@ private static class RemoteChannelLaunchCallable extends MasterToSlaveCallable envOverrides; - RemoteChannelLaunchCallable(@NonNull String[] cmd, @NonNull Pipe out, @NonNull OutputStream err, + RemoteChannelLaunchCallable(@NonNull String[] cmd, @NonNull Pipe out, @NonNull OutputStream err, @CheckForNull String workDir, @NonNull Map envOverrides) { this.cmd = cmd; this.out = out; @@ -1501,7 +1501,7 @@ private static EnvVars inherit(@NonNull Map overrides) { m.overrideExpandingAll(overrides); return m; } - + /** * Debug option to display full current path instead of just the last token. */ diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index 99313e18c703..9b9f38146527 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -219,7 +219,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas private enum PMConstructor { JENKINS { @Override - @NonNull + @NonNull PluginManager doCreate(@NonNull Class klass, @NonNull Jenkins jenkins) throws ReflectiveOperationException { return klass.getConstructor(Jenkins.class).newInstance(jenkins); @@ -1090,7 +1090,7 @@ protected void copyBundledPlugin(URL src, String fileName) throws IOException { } return null; } - + /** * Retrieves input stream for the Manifest url. * The method intelligently handles the case of {@link JarURLConnection} pointing to files within JAR. @@ -1103,11 +1103,11 @@ protected void copyBundledPlugin(URL src, String fileName) throws IOException { URLConnection uc = url.openConnection(); InputStream in = null; // Magic, which allows to avoid using stream generated for JarURLConnection. - // It prevents getting into JENKINS-37332 due to the file descriptor leak + // It prevents getting into JENKINS-37332 due to the file descriptor leak if (uc instanceof JarURLConnection) { final JarURLConnection jarURLConnection = (JarURLConnection) uc; final String entryName = jarURLConnection.getEntryName(); - + try(JarFile jarFile = jarURLConnection.getJarFile()) { final JarEntry entry = entryName != null && jarFile != null ? jarFile.getJarEntry(entryName) : null; if (entry != null) { @@ -1121,16 +1121,16 @@ protected void copyBundledPlugin(URL src, String fileName) throws IOException { url); } } - } + } // If input stream is undefined, use the default implementation if (in == null) { in = url.openStream(); } - + return in; } - + /** * Retrieves modification date of the specified file. * The method intelligently handles the case of {@link JarURLConnection} pointing to files within JAR. @@ -1141,7 +1141,7 @@ protected void copyBundledPlugin(URL src, String fileName) throws IOException { @NonNull /*package*/ static long getModificationDate(@NonNull URL url) throws IOException { URLConnection uc = url.openConnection(); - + // It prevents file descriptor leak if the URL references a file within JAR // See JENKINS-37332 for more info // The code idea is taken from https://github.com/jknack/handlebars.java/pull/394 @@ -1160,7 +1160,7 @@ protected void copyBundledPlugin(URL src, String fileName) throws IOException { } } } - + // Fallbak to the default implementation return uc.getLastModified(); } @@ -1183,31 +1183,31 @@ private void rename(File legacyFile, File newFile) throws IOException { * Creates a hudson.PluginStrategy, looking at the corresponding system property. */ protected PluginStrategy createPluginStrategy() { - String strategyName = SystemProperties.getString(PluginStrategy.class.getName()); - if (strategyName != null) { - try { - Class klazz = getClass().getClassLoader().loadClass(strategyName); - Object strategy = klazz.getConstructor(PluginManager.class) - .newInstance(this); - if (strategy instanceof PluginStrategy) { - LOGGER.info("Plugin strategy: " + strategyName); - return (PluginStrategy) strategy; - } else { - LOGGER.warning("Plugin strategy (" + strategyName + - ") is not an instance of hudson.PluginStrategy"); - } - } catch (ClassNotFoundException e) { - LOGGER.warning("Plugin strategy class not found: " - + strategyName); - } catch (Exception e) { - LOGGER.log(WARNING, "Could not instantiate plugin strategy: " - + strategyName + ". Falling back to ClassicPluginStrategy", e); - } - LOGGER.info("Falling back to ClassicPluginStrategy"); - } - - // default and fallback - return new ClassicPluginStrategy(this); + String strategyName = SystemProperties.getString(PluginStrategy.class.getName()); + if (strategyName != null) { + try { + Class klazz = getClass().getClassLoader().loadClass(strategyName); + Object strategy = klazz.getConstructor(PluginManager.class) + .newInstance(this); + if (strategy instanceof PluginStrategy) { + LOGGER.info("Plugin strategy: " + strategyName); + return (PluginStrategy) strategy; + } else { + LOGGER.warning("Plugin strategy (" + strategyName + + ") is not an instance of hudson.PluginStrategy"); + } + } catch (ClassNotFoundException e) { + LOGGER.warning("Plugin strategy class not found: " + + strategyName); + } catch (Exception e) { + LOGGER.log(WARNING, "Could not instantiate plugin strategy: " + + strategyName + ". Falling back to ClassicPluginStrategy", e); + } + LOGGER.info("Falling back to ClassicPluginStrategy"); + } + + // default and fallback + return new ClassicPluginStrategy(this); } public PluginStrategy getPluginStrategy() { @@ -1347,7 +1347,7 @@ public synchronized void stop() { public static boolean isNonMetaLabel(String label) { return !("adopt-this-plugin".equals(label) || "deprecated".equals(label)); } - + @Restricted(NoExternalUse.class) public HttpResponse doPluginsSearch(@QueryParameter String query, @QueryParameter Integer limit) { List plugins = new ArrayList<>(); @@ -1458,10 +1458,10 @@ public HttpResponse doPluginsSearch(@QueryParameter String query, @QueryParamete JSONArray mappedPlugins = new JSONArray(); mappedPlugins.addAll(plugins); - + return hudson.util.HttpResponses.okJSON(mappedPlugins); } - + /** * Get the list of all plugins - available and installed. * @return The list of all plugins - available and installed. @@ -1498,8 +1498,8 @@ public HttpResponse doPlugins() { for (UpdateSite.Plugin plugin: site.getAvailables()) { JSONObject pluginInfo = allPlugins.get(plugin.name); if(pluginInfo == null) { - pluginInfo = new JSONObject(); - pluginInfo.put("installed", false); + pluginInfo = new JSONObject(); + pluginInfo.put("installed", false); } pluginInfo.put("name", plugin.name); pluginInfo.put("title", plugin.getDisplayName()); @@ -1532,9 +1532,9 @@ public HttpResponse doUpdateSources(StaplerRequest req) throws IOException { return new HttpRedirect("./sites"); } - + /** - * Called to progress status beyond installing plugins, e.g. if + * Called to progress status beyond installing plugins, e.g. if * there were failures that prevented installation from naturally proceeding */ @RequirePOST @@ -1651,7 +1651,7 @@ private List> install(@NonNull Collection, ModelObject { * The snapshot of {@code disableFile.exists()} as of the start up. */ private final boolean active; - + private boolean hasCycleDependency = false; private final List dependencies; @@ -384,11 +384,11 @@ public boolean isDeprecated() { /** * Inject the specified jar file(s) to the plugins classpath. *

Warning: This is advanced usage that you should not be needed in 99.9% of all cases, any jar insertion - * should happen early into the plugins lifecycle to prevent classloading issues in dependent plugins. + * should happen early into the plugins lifecycle to prevent classloading issues in dependent plugins. *

* Rather than use this functionality it is to have co-operative behaviour between any consumer of the libraries and load the classes in a separate {@link ClassLoader}. * you can expose third-party libraries from a dynamic location in various ways, such as: - * + * *

    *
  • You could split your plugin into two modules: *
      @@ -409,7 +409,7 @@ public boolean isDeprecated() { * For a concrete example see the database * plugin. * - * + * * @throws Exception if the File could not be inserted into the classpath for some reason. * @since 2.313 */ @@ -467,7 +467,7 @@ public Dependency(String s) { @Override public String toString() { return shortName + " (" + version + ")" + (optional ? " optional" : ""); - } + } } /** @@ -484,18 +484,18 @@ public String toString() { * @param dependencies a list of mandatory dependencies * @param optionalDependencies a list of optional dependencies */ - public PluginWrapper(PluginManager parent, File archive, Manifest manifest, URL baseResourceURL, - ClassLoader classLoader, File disableFile, - List dependencies, List optionalDependencies) { + public PluginWrapper(PluginManager parent, File archive, Manifest manifest, URL baseResourceURL, + ClassLoader classLoader, File disableFile, + List dependencies, List optionalDependencies) { this.parent = parent; - this.manifest = manifest; - this.shortName = Util.intern(computeShortName(manifest, archive.getName())); - this.baseResourceURL = baseResourceURL; - this.classLoader = classLoader; - this.disableFile = disableFile; - this.active = !disableFile.exists(); - this.dependencies = dependencies; - this.optionalDependencies = optionalDependencies; + this.manifest = manifest; + this.shortName = Util.intern(computeShortName(manifest, archive.getName())); + this.baseResourceURL = baseResourceURL; + this.classLoader = classLoader; + this.disableFile = disableFile; + this.active = !disableFile.exists(); + this.dependencies = dependencies; + this.optionalDependencies = optionalDependencies; for (Dependency d : optionalDependencies) { assert d.optional : d + " included among optionalDependencies of " + shortName + " but was not marked optional"; } @@ -608,7 +608,7 @@ public String getUrl() { List siteMetadataList = getInfoFromAllSites(); String firstSiteUrl = null; if (!siteMetadataList.isEmpty()) { - firstSiteUrl = siteMetadataList.get(0).wiki; + firstSiteUrl = siteMetadataList.get(0).wiki; if (allUrlsMatch(firstSiteUrl, siteMetadataList)) { return firstSiteUrl; } @@ -618,7 +618,7 @@ public String getUrl() { // use manifest (since maven-hpi-plugin 1.30) String url = manifest.getMainAttributes().getValue("Url"); if (url != null) { - return url; + return url; } return firstSiteUrl; } @@ -627,7 +627,7 @@ private boolean allUrlsMatch(String url, List uiList) { return uiList.stream().allMatch(k -> k.wiki != null && k.wiki.equals(url)); } - @Override + @Override public String toString() { return "Plugin:" + getShortName(); } @@ -718,7 +718,7 @@ public boolean isOlderThan(VersionNumber v) { return getVersionNumber().compareTo(v) < 0; } catch (IllegalArgumentException e) { // if we can't figure out our current version, it probably means it's very old, - // since the version information is missing only from the very old plugins + // since the version information is missing only from the very old plugins return true; } } @@ -889,7 +889,7 @@ private Set dependentsToCheck(PluginDisableStrategy strategy) { public boolean isActive() { return active && !hasCycleDependency(); } - + public boolean hasCycleDependency(){ return hasCycleDependency; } @@ -1056,7 +1056,7 @@ public UpdateSite.Plugin getUpdateInfo() { if(p!=null && p.isNewerThan(getVersion())) return p; return null; } - + /** * returns the {@link hudson.model.UpdateSite.Plugin} object, or null. */ @@ -1083,7 +1083,7 @@ private List getInfoFromAllSites() { public boolean hasUpdate() { return getUpdateInfo()!=null; } - + @Exported @Deprecated // See https://groups.google.com/d/msg/jenkinsci-dev/kRobm-cxFw8/6V66uhibAwAJ public boolean isPinned() { @@ -1376,7 +1376,7 @@ public HttpResponse doUnpin() throws IOException { @RequirePOST public HttpResponse doDoUninstall() throws IOException { Jenkins jenkins = Jenkins.get(); - + jenkins.checkPermission(Jenkins.ADMINISTER); Files.deleteIfExists(Util.fileToPath(archive)); diff --git a/core/src/main/java/hudson/Util.java b/core/src/main/java/hudson/Util.java index df22f9faab86..e66820214612 100644 --- a/core/src/main/java/hudson/Util.java +++ b/core/src/main/java/hudson/Util.java @@ -1188,7 +1188,7 @@ public static String getFileName(@NonNull String filePath) { /** * Concatenate multiple strings by inserting a separator. - * @deprecated since TODO; use {@link String#join(CharSequence, Iterable)} + * @deprecated since 2.292; use {@link String#join(CharSequence, Iterable)} */ @Deprecated @NonNull diff --git a/core/src/main/java/hudson/WebAppMain.java b/core/src/main/java/hudson/WebAppMain.java index f22fb7b08e7a..82aee9f2f9ac 100644 --- a/core/src/main/java/hudson/WebAppMain.java +++ b/core/src/main/java/hudson/WebAppMain.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Jean-Baptiste Quenot, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -29,7 +29,6 @@ import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; import com.thoughtworks.xstream.core.JVM; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.Hudson; import hudson.security.ACL; import hudson.security.ACLContext; @@ -97,7 +96,7 @@ public class WebAppMain implements ServletContextListener { *

      * The SecurityRealm should be corrected but this is a hardening in Jenkins core. *

      - * As this property is read during startup, you will not be able to change it at runtime + * As this property is read during startup, you will not be able to change it at runtime * depending on your application server (not possible with Jetty nor Tomcat) *

      * When running hpi:run, the default tracking is COOKIE+URL. @@ -108,7 +107,7 @@ public class WebAppMain implements ServletContextListener { public static final String FORCE_SESSION_TRACKING_BY_COOKIE_PROP = WebAppMain.class.getName() + ".forceSessionTrackingByCookie"; private final RingBufferLogHandler handler = new RingBufferLogHandler(WebAppMain.getDefaultRingBufferSize()) { - + @Override public synchronized void publish(LogRecord record) { if (record.getLevel().intValue() >= Level.INFO.intValue()) { super.publish(record); @@ -141,7 +140,7 @@ public void contextInitialized(ServletContextEvent event) { if (Main.isDevelopmentMode && System.getProperty("java.util.logging.config.file") == null) { try { Formatter formatter = (Formatter) Class.forName("io.jenkins.lib.support_log_formatter.SupportLogFormatter").newInstance(); - for (Handler h : java.util.logging.Logger.getLogger("").getHandlers()) { + for (Handler h : Logger.getLogger("").getHandlers()) { if (h instanceof ConsoleHandler) { ((ConsoleHandler) h).setFormatter(formatter); } @@ -240,7 +239,6 @@ public Locale get() { final File _home = home; initThread = new Thread("Jenkins initialization thread") { - @SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED_BAD_PRACTICE", justification = "TODO needs triage") @Override public void run() { boolean success = false; @@ -253,7 +251,7 @@ public void run() { context.setAttribute(APP, instance); - BootFailure.getBootFailureFile(_home).delete(); + Files.deleteIfExists(BootFailure.getBootFailureFile(_home).toPath()); // at this point we are open for business and serving requests normally LOGGER.info("Jenkins is fully up and running"); @@ -301,10 +299,9 @@ public static void installExpressionFactory(ServletContextEvent event) { JellyFacet.setExpressionFactory(event, new ExpressionFactory2()); } - /** + /** * Installs log handler to monitor all Hudson logs. */ - @SuppressFBWarnings(value = "LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE", justification = "TODO needs triage") private void installLogger() { Jenkins.logRecords = handler.getView(); Logger.getLogger("").addHandler(handler); @@ -329,7 +326,7 @@ public FileAndDescription(File file,String description) { *

      * People makes configuration mistakes, so we are trying to be nice * with those by doing {@link String#trim()}. - * + * *

      * @return the File alongside with some description to help the user troubleshoot issues */ diff --git a/core/src/main/java/hudson/cli/declarative/CLIMethod.java b/core/src/main/java/hudson/cli/declarative/CLIMethod.java index 2aecb963df3f..13ddffbf5d2f 100644 --- a/core/src/main/java/hudson/cli/declarative/CLIMethod.java +++ b/core/src/main/java/hudson/cli/declarative/CLIMethod.java @@ -63,7 +63,7 @@ @Documented public @interface CLIMethod { /** - * CLI command name. Used as {@link CLICommand#getName()} + * CLI command name. Used as {@link CLICommand#getName()} */ String name(); diff --git a/core/src/main/java/hudson/console/AnnotatedLargeText.java b/core/src/main/java/hudson/console/AnnotatedLargeText.java index dafff632d305..d3f8aa3301bd 100644 --- a/core/src/main/java/hudson/console/AnnotatedLargeText.java +++ b/core/src/main/java/hudson/console/AnnotatedLargeText.java @@ -103,7 +103,7 @@ public void doProgressiveText(StaplerRequest req, StaplerResponse rsp) throws IO /** * For reusing code between text/html and text/plain, we run them both through the same code path - * and use this request attribute to differentiate. + * and use this request attribute to differentiate. */ private boolean isHtml() { StaplerRequest req = Stapler.getCurrentRequest(); diff --git a/core/src/main/java/hudson/init/Initializer.java b/core/src/main/java/hudson/init/Initializer.java index 07f328a20eef..61b1c272be7c 100644 --- a/core/src/main/java/hudson/init/Initializer.java +++ b/core/src/main/java/hudson/init/Initializer.java @@ -51,7 +51,7 @@ public static void init() throws IOException { * The method in question can be either {@code static} or an instance method. When used with instance * methods, those methods have to be on a class annotated with {@link Extension} and marked as * {@link #after()} {@link InitMilestone#PLUGINS_PREPARED}. - * + * * @author Kohsuke Kawaguchi */ @Indexed @@ -99,7 +99,7 @@ public static void init() throws IOException { /** * Should the failure in this task prevent Hudson from starting up? * - * @see Task#failureIsFatal() + * @see Task#failureIsFatal() */ boolean fatal() default true; } diff --git a/core/src/main/java/hudson/init/impl/GroovyInitScript.java b/core/src/main/java/hudson/init/impl/GroovyInitScript.java index fb37be78b264..69a36cc18e3e 100644 --- a/core/src/main/java/hudson/init/impl/GroovyInitScript.java +++ b/core/src/main/java/hudson/init/impl/GroovyInitScript.java @@ -32,7 +32,7 @@ /** * Run the initialization script, if it exists. * It runs strictly after the initialization of other tasks during the last initialization milestone. - * + * * @author Kohsuke Kawaguchi */ public class GroovyInitScript { diff --git a/core/src/main/java/hudson/lifecycle/RestartNotSupportedException.java b/core/src/main/java/hudson/lifecycle/RestartNotSupportedException.java index 08bae8291c06..50f87f457044 100644 --- a/core/src/main/java/hudson/lifecycle/RestartNotSupportedException.java +++ b/core/src/main/java/hudson/lifecycle/RestartNotSupportedException.java @@ -2,7 +2,7 @@ /** * Indicates that the {@link Lifecycle} doesn't support restart. - * + * * @author Kohsuke Kawaguchi */ public class RestartNotSupportedException extends Exception { diff --git a/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java b/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java index 8612f2cf0d6f..0eb1b43cb388 100644 --- a/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java +++ b/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -43,7 +43,7 @@ /** * {@link Lifecycle} for Hudson installed as Windows service. - * + * * @author Kohsuke Kawaguchi * @see WindowsInstallerLink */ @@ -143,10 +143,10 @@ public void restart() throws IOException, InterruptedException { if(r!=0) throw new IOException(baos.toString()); } - + private static File getBaseDir() { File baseDir; - + String baseEnv = System.getenv("BASE"); if (baseEnv != null) { baseDir = new File(baseEnv); diff --git a/core/src/main/java/hudson/logging/LogRecorderManager.java b/core/src/main/java/hudson/logging/LogRecorderManager.java index 3d7164a2dcd9..8a13849f3f89 100644 --- a/core/src/main/java/hudson/logging/LogRecorderManager.java +++ b/core/src/main/java/hudson/logging/LogRecorderManager.java @@ -32,6 +32,7 @@ import hudson.RestrictedSince; import hudson.init.Initializer; import hudson.model.AbstractModelObject; +import hudson.model.Failure; import hudson.model.RSS; import hudson.util.CopyOnWriteMap; import java.io.File; @@ -39,12 +40,14 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.function.Function; import java.util.logging.Level; +import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.Logger; import javax.servlet.ServletException; @@ -170,8 +173,11 @@ public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse /** * Configure the logging level. */ - @SuppressFBWarnings(value = "LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE", justification = "TODO needs triage") @RequirePOST + @SuppressFBWarnings( + value = "LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE", + justification = + "if the logger is known, then we have a reference to it in LogRecorder#loggers") public HttpResponse doConfigLogger(@QueryParameter String name, @QueryParameter String level) { Jenkins.get().checkPermission(Jenkins.ADMINISTER); Level lv; @@ -179,8 +185,14 @@ public HttpResponse doConfigLogger(@QueryParameter String name, @QueryParameter lv = null; else lv = Level.parse(level.toUpperCase(Locale.ENGLISH)); - Logger.getLogger(name).setLevel(lv); - return new HttpRedirect("levels"); + Logger target; + if (Collections.list(LogManager.getLogManager().getLoggerNames()).contains(name) + && (target = Logger.getLogger(name)) != null) { + target.setLevel(lv); + return new HttpRedirect("levels"); + } else { + throw new Failure(Messages.LogRecorderManager_LoggerNotFound(name)); + } } /** diff --git a/core/src/main/java/hudson/model/AbstractBuild.java b/core/src/main/java/hudson/model/AbstractBuild.java index 07e965821e4f..a6ea4845b0db 100644 --- a/core/src/main/java/hudson/model/AbstractBuild.java +++ b/core/src/main/java/hudson/model/AbstractBuild.java @@ -462,7 +462,7 @@ protected Lease decideWorkspace(@NonNull Node n, WorkspaceList wsl) throws Inter @Override public Result run(@NonNull BuildListener listener) throws Exception { final Node node = getCurrentNode(); - + assert builtOn==null; builtOn = node.getNodeName(); hudsonVersion = Jenkins.VERSION; @@ -502,7 +502,7 @@ public Result run(@NonNull BuildListener listener) throws Exception { } else { listener.getLogger().print(Messages.AbstractBuild_Building()); } - + lease = decideWorkspace(node, Computer.currentComputer().getWorkspaceList()); workspace = lease.path.getRemote(); @@ -883,11 +883,11 @@ public boolean tearDown(AbstractBuild build, BuildListener listener) throws IOEx } } - /* + /* * No need to lock the entire AbstractBuild on change set calculation */ private transient Object changeSetLock = new Object(); - + /** * Gets the changes incorporated into this build. * @@ -897,7 +897,7 @@ public boolean tearDown(AbstractBuild build, BuildListener listener) throws IOEx @NonNull public ChangeLogSet getChangeSet() { synchronized (changeSetLock) { if (scm==null) { - scm = NullChangeLogParser.INSTANCE; + scm = NullChangeLogParser.INSTANCE; } } @@ -973,13 +973,13 @@ public EnvVars getEnvironment(TaskListener log) throws IOException, InterruptedE /** * During the build, expose the environments contributed by {@link BuildWrapper}s and others. - * + * *

      * Since 1.444, executor thread that's doing the build can access mutable underlying list, * which allows the caller to add/remove environments. The recommended way of adding * environment is through {@link BuildWrapper}, but this might be handy for build steps * who wants to expose additional environment variables to the rest of the build. - * + * * @return can be empty list, but never null. Immutable. * @since 1.437 */ @@ -987,9 +987,9 @@ public EnvironmentList getEnvironments() { Executor e = Executor.currentExecutor(); if (e!=null && e.getCurrentExecutable()==this) { if (buildEnvironments==null) buildEnvironments = new ArrayList<>(); - return new EnvironmentList(buildEnvironments); + return new EnvironmentList(buildEnvironments); } - + return new EnvironmentList(buildEnvironments==null ? Collections.emptyList() : Collections.unmodifiableList(new ArrayList<>(buildEnvironments))); } @@ -1004,7 +1004,7 @@ public Calendar due() { @Override public void addAction(Action a) { super.addAction(a); } - + @SuppressWarnings("deprecation") public List getPersistentActions(){ return super.getActions(); @@ -1036,7 +1036,7 @@ public Set getSensitiveBuildVariables() { bw.makeSensitiveBuildVariables(this, s); } } - + return s; } @@ -1394,7 +1394,7 @@ public void doStop(StaplerRequest req, StaplerResponse rsp) throws IOException, * * If we use this/executor/stop URL, it causes 404 if the build is already killed, * as {@link #getExecutor()} returns null. - * + * * @since 1.489 */ @RequirePOST diff --git a/core/src/main/java/hudson/model/AbstractItem.java b/core/src/main/java/hudson/model/AbstractItem.java index 58a1d90bc5cb..47a715a0aa12 100644 --- a/core/src/main/java/hudson/model/AbstractItem.java +++ b/core/src/main/java/hudson/model/AbstractItem.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Daniel Dyer, Tom Huybrechts, Yahoo!, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -124,7 +124,7 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet protected volatile String description; private transient ItemGroup parent; - + protected String displayName; protected AbstractItem(ItemGroup parent, String name) { @@ -168,7 +168,7 @@ public String getDisplayName() { // if the displayName is not set, then return the name as we use to do return getName(); } - + /** * This is intended to be used by the Job configuration pages where * we want to return null if the display name is not set. @@ -179,21 +179,21 @@ public String getDisplayName() { public String getDisplayNameOrNull() { return displayName; } - + /** - * This method exists so that the Job configuration pages can use + * This method exists so that the Job configuration pages can use * getDisplayNameOrNull so that nothing is shown in the display name text * box if the display name is not set. */ public void setDisplayNameOrNull(String displayName) throws IOException { setDisplayName(displayName); } - + public void setDisplayName(String displayName) throws IOException { this.displayName = Util.fixEmptyAndTrim(displayName); save(); } - + @Override public File getRootDir() { return getParent().getRootDirFor(this); @@ -488,7 +488,7 @@ public final String getFullDisplayName() { if(n.length()==0) return getDisplayName(); else return n+" » "+getDisplayName(); } - + /** * Gets the display name of the current item relative to the given group. * @@ -500,7 +500,7 @@ public final String getFullDisplayName() { public String getRelativeDisplayNameFrom(ItemGroup p) { return Functions.getRelativeDisplayNameFrom(this, p); } - + /** * This method only exists to disambiguate {@link #getRelativeNameFrom(ItemGroup)} and {@link #getRelativeNameFrom(Item)} * @since 1.512 @@ -527,7 +527,7 @@ public void onLoad(ItemGroup parent, String name) throws IOExcep * to perform any implementation-specific work. * *

      - * + * * * @param src * Item from which it's copied from. The same type as {@code this}. Never null. @@ -740,8 +740,8 @@ public void delete() throws IOException, InterruptedException { final WorkUnit workUnit = e.getCurrentWorkUnit(); final Executable executable = workUnit != null ? workUnit.getExecutable() : null; final SubTask subtask = executable != null ? getParentOf(executable) : null; - - if (subtask != null) { + + if (subtask != null) { Item item = Tasks.getItemOf(subtask); while (item != null) { if (item == this) { diff --git a/core/src/main/java/hudson/model/AbstractProject.java b/core/src/main/java/hudson/model/AbstractProject.java index 48666d0bad24..cd669b8bb494 100644 --- a/core/src/main/java/hudson/model/AbstractProject.java +++ b/core/src/main/java/hudson/model/AbstractProject.java @@ -1105,7 +1105,7 @@ public AbstractProject getBuildingDownstream() { Set unblockedTasks = Jenkins.get().getQueue().getUnblockedTasks(); for (AbstractProject tup : getTransitiveDownstreamProjects()) { - if (tup!=this && (tup.isBuilding() || unblockedTasks.contains(tup))) + if (tup!=this && (tup.isBuilding() || unblockedTasks.contains(tup))) return tup; } return null; @@ -1122,7 +1122,7 @@ public AbstractProject getBuildingUpstream() { Set unblockedTasks = Jenkins.get().getQueue().getUnblockedTasks(); for (AbstractProject tup : getTransitiveUpstreamProjects()) { - if (tup!=this && (tup.isBuilding() || unblockedTasks.contains(tup))) + if (tup!=this && (tup.isBuilding() || unblockedTasks.contains(tup))) return tup; } return null; @@ -1932,10 +1932,10 @@ public FormValidation doCheckLabel(@AncestorInPath AbstractProject project, } public FormValidation doCheckCustomWorkspace(@QueryParameter String customWorkspace){ - if(Util.fixEmptyAndTrim(customWorkspace)==null) - return FormValidation.error(Messages.AbstractProject_CustomWorkspaceEmpty()); - else - return FormValidation.ok(); + if(Util.fixEmptyAndTrim(customWorkspace)==null) + return FormValidation.error(Messages.AbstractProject_CustomWorkspaceEmpty()); + else + return FormValidation.ok(); } public AutoCompletionCandidates doAutoCompleteUpstreamProjects(@QueryParameter String value) { diff --git a/core/src/main/java/hudson/model/AperiodicWork.java b/core/src/main/java/hudson/model/AperiodicWork.java index c275968168f4..4fd5e231072a 100644 --- a/core/src/main/java/hudson/model/AperiodicWork.java +++ b/core/src/main/java/hudson/model/AperiodicWork.java @@ -41,37 +41,37 @@ /** * Extension point which allows scheduling a task with variable interval. Interval in evaluated every time before next * task is scheduled by calling {@link #getRecurrencePeriod()}. Task to be scheduled is obtain by calling {@link #getNewInstance()}. - * + * *

      * This class is similar to {@link PeriodicWork}. The main difference is in re-evaluating delay interval every time. * See {@link PeriodicWork} for details. Analog of {@link AsyncPeriodicWork} is {@link AsyncAperiodicWork}. - * + * * @author vjuranek * @since 1.410 */ @SuppressFBWarnings(value="PREDICTABLE_RANDOM", justification = "The random is just used for an initial delay.") public abstract class AperiodicWork extends SafeTimerTask implements ExtensionPoint { - - protected final Logger logger = Logger.getLogger(getClass().getName()); - + + protected final Logger logger = Logger.getLogger(getClass().getName()); + /** * Gets the number of milliseconds between successive executions. * *

      - * Jenkins calls this method every time the timer task is scheduled. + * Jenkins calls this method every time the timer task is scheduled. * */ public abstract long getRecurrencePeriod(); /** - * Gets new instance of task to be executed. Method should return new instance each time, as there no check, if previously + * Gets new instance of task to be executed. Method should return new instance each time, as there no check, if previously * scheduled task already finished. Returning same instance could lead to throwing {@link IllegalStateException} (especially * in case of {@link AsyncAperiodicWork}) and therefore scheduling of next tasks will be broken. - * + * * @return AperiodicWork - timer task instance to be executed */ public abstract AperiodicWork getNewInstance(); - + /** * Gets the number of milliseconds till the first execution. * @@ -88,7 +88,7 @@ public long getInitialDelay() { @Override public final void doRun() throws Exception{ - doAperiodicRun(); + doAperiodicRun(); Timer.get().schedule(getNewInstance(), getRecurrencePeriod(), TimeUnit.MILLISECONDS); } @@ -107,7 +107,7 @@ private static void scheduleAperiodWork(AperiodicWork ap) { } protected abstract void doAperiodicRun(); - + /** * Returns all the registered {@link AperiodicWork}s. */ diff --git a/core/src/main/java/hudson/model/Build.java b/core/src/main/java/hudson/model/Build.java index 1e82fc04618a..7daa7b4cf0b0 100644 --- a/core/src/main/java/hudson/model/Build.java +++ b/core/src/main/java/hudson/model/Build.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -78,7 +78,7 @@ * *

      * And beyond that, the build is considered complete, and from then on {@link Build} object is there to - * keep the record of what happened in this build. + * keep the record of what happened in this build. * * @author Kohsuke Kawaguchi */ @@ -148,7 +148,7 @@ protected Result doRun(@NonNull BuildListener listener) throws Exception { Result r = null; try { List wrappers = new ArrayList<>(project.getBuildWrappers().values()); - + ParametersAction parameters = getAction(ParametersAction.class); if (parameters != null) parameters.createBuildWrappers(Build.this,wrappers); @@ -199,7 +199,7 @@ private boolean build(@NonNull BuildListener listener, @NonNull Collection * This can be implemented by {@link Action}s that associate themselves - * with {@link Run}. + * with {@link Run}. * *

      * Actions with this marker should have a view {@code badge.jelly}, diff --git a/core/src/main/java/hudson/model/ComputerSet.java b/core/src/main/java/hudson/model/ComputerSet.java index db4292989e49..770e25814c3e 100644 --- a/core/src/main/java/hudson/model/ComputerSet.java +++ b/core/src/main/java/hudson/model/ComputerSet.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Stephen Connolly, Thomas J. Black - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -227,7 +227,7 @@ public void do_launchAll(StaplerRequest req, StaplerResponse rsp) throws IOExcep @RequirePOST public void doUpdateNow( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.MANAGE); - + for (NodeMonitor nodeMonitor : NodeMonitor.getAll()) { Thread t = nodeMonitor.triggerUpdate(); String columnCaption = nodeMonitor.getColumnCaption(); @@ -298,7 +298,7 @@ public synchronized void doDoCreateItem( StaplerRequest req, StaplerResponse rsp JSONObject formData = req.getSubmittedForm(); formData.put("name", fixedName); - + // TODO type is probably NodeDescriptor.id but confirm Node result = NodeDescriptor.all().find(type).newInstance(req, formData); app.addNode(result); @@ -333,7 +333,7 @@ public FormValidation doCheckName(@QueryParameter String value) throws IOExcepti if(Util.fixEmpty(value)==null) return FormValidation.ok(); - + try { checkName(value); return FormValidation.ok(); @@ -341,7 +341,7 @@ public FormValidation doCheckName(@QueryParameter String value) throws IOExcepti return FormValidation.error(e.getMessage()); } } - + /** * Accepts submission from the configuration page. */ diff --git a/core/src/main/java/hudson/model/Describable.java b/core/src/main/java/hudson/model/Describable.java index ae8103b3cfd9..e1331510d7e1 100644 --- a/core/src/main/java/hudson/model/Describable.java +++ b/core/src/main/java/hudson/model/Describable.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/hudson/model/Descriptor.java b/core/src/main/java/hudson/model/Descriptor.java index 5b94ff25b1b4..b1066e7428e3 100644 --- a/core/src/main/java/hudson/model/Descriptor.java +++ b/core/src/main/java/hudson/model/Descriptor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -136,7 +136,7 @@ * {@link Descriptor} defines addition to the standard Java reflection * and provides reflective information about its corresponding {@link Describable}. * These are primarily used by tag libraries to - * keep the Jelly scripts concise. + * keep the Jelly scripts concise. * * @author Kohsuke Kawaguchi * @see Describable @@ -241,7 +241,7 @@ public List getApplicableItemDescriptors() { /** * Help file redirect, keyed by the field name to the path. * - * @see #getHelpFile(String) + * @see #getHelpFile(String) */ private final transient Map helpRedirect = new HashMap<>(2); @@ -279,7 +279,7 @@ protected Descriptor(Class clazz) { * Infers the type of the corresponding {@link Describable} from the outer class. * This version works when you follow the common convention, where a descriptor * is written as the static nested class of the describable class. - * + * * @since 1.278 */ protected Descriptor() { @@ -335,7 +335,7 @@ public String getDisplayName() { * * @return * Stick to valid Java identifier character, plus '.', which had to be allowed for historical reasons. - * + * * @since 1.391 */ public String getId() { @@ -537,7 +537,7 @@ public final String getJsonSafeClassName() { /** * @deprecated * Implement {@link #newInstance(StaplerRequest, JSONObject)} method instead. - * Deprecated as of 1.145. + * Deprecated as of 1.145. */ @Deprecated public T newInstance(StaplerRequest req) throws FormException { @@ -769,7 +769,7 @@ public String getHelpFile(Klass clazz, String fieldName) { } return null; } - + /** * Tells Jenkins that the help file for the field 'fieldName' is defined in the help file for * the 'fieldNameToRedirectTo' in the 'owner' class. diff --git a/core/src/main/java/hudson/model/Executor.java b/core/src/main/java/hudson/model/Executor.java index cf00f7be5665..f719b65c52eb 100644 --- a/core/src/main/java/hudson/model/Executor.java +++ b/core/src/main/java/hudson/model/Executor.java @@ -248,7 +248,7 @@ public Result abortResult() { // this method is almost always called as a result of the current thread being interrupted // as a result we need to clean the interrupt flag so that the lock's lock method doesn't // get confused and think it was interrupted while awaiting the lock - Thread.interrupted(); + Thread.interrupted(); // we need to use a write lock as we may be repeatedly interrupted while processing and // we need the same lock as used in void interrupt(Result,boolean,CauseOfInterruption...) // JENKINS-28690 @@ -539,12 +539,12 @@ public Queue.Executable getCurrentExecutableForApi() { Executable candidate = getCurrentExecutable(); return candidate instanceof AccessControlled && ((AccessControlled) candidate).hasPermission(Item.READ) ? candidate : null; } - + /** * Returns causes of interruption. * * @return Unmodifiable collection of causes of interruption. - * @since 1.617 + * @since 1.617 */ public @NonNull Collection getCausesOfInterruption() { return Collections.unmodifiableCollection(causes); diff --git a/core/src/main/java/hudson/model/Fingerprint.java b/core/src/main/java/hudson/model/Fingerprint.java index 19c8a17feced..fbdb97f7722a 100644 --- a/core/src/main/java/hudson/model/Fingerprint.java +++ b/core/src/main/java/hudson/model/Fingerprint.java @@ -1277,7 +1277,7 @@ public synchronized void save() throws IOException { /** * Save the Fingerprint in the given file locally * @throws IOException Save error - * @deprecated as of TODO. Use {@link #save()} instead. + * @deprecated as of 2.242. Use {@link #save()} instead. */ @Deprecated void save(File file) throws IOException { @@ -1368,7 +1368,7 @@ public Api getApi() { /** * Determines the file name from md5sum. - * @deprecated as of TODO. Use {@link #load(String)} instead. + * @deprecated as of 2.242. Use {@link #load(String)} instead. */ @Deprecated /*package*/ static @CheckForNull Fingerprint load(@NonNull byte[] md5sum) throws IOException { @@ -1379,7 +1379,7 @@ public Api getApi() { * Loads a {@link Fingerprint} from a file in the image. * @return Loaded {@link Fingerprint}. Null if the config file does not exist or * malformed. - * @deprecated as of TODO. Use {@link #load(String)} instead. + * @deprecated as of 2.242. Use {@link #load(String)} instead. */ @Deprecated /*package*/ static @CheckForNull Fingerprint load(@NonNull File file) throws IOException { diff --git a/core/src/main/java/hudson/model/HealthReportingAction.java b/core/src/main/java/hudson/model/HealthReportingAction.java index 024c9488725f..c5fa8f0e8894 100644 --- a/core/src/main/java/hudson/model/HealthReportingAction.java +++ b/core/src/main/java/hudson/model/HealthReportingAction.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Stephen Connolly - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -42,7 +42,7 @@ public interface HealthReportingAction extends Action { * Get this {@link Action}'s {@link HealthReport}. * * @return - * The health report for this instance of the Action or + * The health report for this instance of the Action or * {@code null} if the Action does not want to * contribute a HealthReport. */ diff --git a/core/src/main/java/hudson/model/InvisibleAction.java b/core/src/main/java/hudson/model/InvisibleAction.java index bb8c3b14ebe9..d921cd12f8d9 100644 --- a/core/src/main/java/hudson/model/InvisibleAction.java +++ b/core/src/main/java/hudson/model/InvisibleAction.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -31,7 +31,7 @@ * {@link Action} for just storing data associated with a build. * *

      - * It could also be used to reduce the amount of code required to just create an accessible url for tests + * It could also be used to reduce the amount of code required to just create an accessible url for tests * by overriding the {@link #getUrlName()} method. * * @author Kohsuke Kawaguchi diff --git a/core/src/main/java/hudson/model/Job.java b/core/src/main/java/hudson/model/Job.java index 1e0d90c8ca1e..2658ce50c20f 100644 --- a/core/src/main/java/hudson/model/Job.java +++ b/core/src/main/java/hudson/model/Job.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt, Matthew R. Harrah, Red Hat, Inc., Stephen Connolly, Tom Huybrechts, CloudBees, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -123,7 +123,7 @@ /** * A job is an runnable entity under the monitoring of Hudson. - * + * *

      * Every time it "runs", it will be recorded as a {@link Run} object. * @@ -132,7 +132,6 @@ * * @author Kohsuke Kawaguchi */ -@SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "TODO needs triage") public abstract class Job, RunT extends Run> extends AbstractItem implements ExtensionPoint, StaplerOverridable, ModelObjectWithChildren { @@ -305,14 +304,14 @@ public boolean isBuilding() { RunT b = getLastBuild(); return b!=null && b.isBuilding(); } - + /** * Returns true if the log file is still being updated. */ public boolean isLogUpdated() { RunT b = getLastBuild(); return b!=null && b.isLogUpdated(); - } + } @Override public String getPronoun() { @@ -383,7 +382,7 @@ public EnvVars getCharacteristicEnvVars() { if (node != null) { final Computer computer = node.toComputer(); if (computer != null) { - // we need to get computer environment to inherit platform details + // we need to get computer environment to inherit platform details env = computer.getEnvironment(); env.putAll(computer.buildEnvironment(listener)); } @@ -406,12 +405,12 @@ public EnvVars getCharacteristicEnvVars() { /** * Programmatically updates the next build number. - * + * *

      * Much of Hudson assumes that the build number is unique and monotonic, so * this method can only accept a new value that's bigger than * {@link #getLastBuild()} returns. Otherwise it'll be no-op. - * + * * @since 1.199 (before that, this method was package private.) */ public synchronized void updateNextBuildNumber(int next) throws IOException { @@ -510,7 +509,7 @@ public Collection getAllJobs() { /** * Adds {@link JobProperty}. - * + * * @since 1.188 */ public void addProperty(JobProperty jobProp) throws IOException { @@ -726,7 +725,7 @@ public void onLocationChanged(Item item, String oldFullName, String newFullName) /** * Gets the read-only view of all the builds. - * + * * @return never null. The first entry is the latest build. */ @Exported(name="allBuilds",visibility=-2) @@ -818,7 +817,7 @@ public RunT getBuildForCLI(@Argument(required=true,metaVar="BUILD#",usage="Build /** * Gets the youngest build #m that satisfies {@code n<=m}. - * + * * This is useful when you'd like to fetch a build but the exact build might * be already gone (deleted, rotated, etc.) * @see LazyBuildMixIn#getNearestBuild @@ -833,7 +832,7 @@ public RunT getNearestBuild(int n) { /** * Gets the latest build #m that satisfies {@code m<=n}. - * + * * This is useful when you'd like to fetch a build but the exact build might * be already gone (deleted, rotated, etc.) * @see LazyBuildMixIn#getNearestOldBuild @@ -874,7 +873,7 @@ public Object getDynamic(String token, StaplerRequest req, * Some {@link Job}s may not have backing data store for {@link Run}s, but * those {@link Job}s that use file system for storing data should use this * directory for consistency. - * + * * @see RunMap */ public File getBuildDir() { @@ -890,7 +889,7 @@ public File getBuildDir() { /** * Gets all the runs. - * + * * The resulting map must be treated immutable (by employing copy-on-write * semantics.) The map is descending order, with newest builds at the top. * @see LazyBuildMixIn#_getRuns @@ -899,7 +898,7 @@ public File getBuildDir() { /** * Called from {@link Run} to remove it from this job. - * + * * The files are deleted already. So all the callee needs to do is to remove * a reference from this {@link Job}. * @see LazyBuildMixIn#removeRun @@ -937,7 +936,7 @@ public RunT getFirstBuild() { /** * Returns the last successful build, if any. Otherwise null. A successful build * would include either {@link Result#SUCCESS} or {@link Result#UNSTABLE}. - * + * * @see #getLastStableBuild() */ @Exported @@ -993,10 +992,10 @@ public RunT getLastFailedBuild() { public RunT getLastCompletedBuild() { return (RunT)Permalink.LAST_COMPLETED_BUILD.resolve(this); } - + /** * Returns the last {@code numberOfBuilds} builds with a build result ≥ {@code threshold} - * + * * @return a list with the builds. May be smaller than 'numberOfBuilds' or even empty * if not enough builds satisfying the threshold have been found. Never null. */ @@ -1004,13 +1003,13 @@ public List getLastBuildsOverThreshold(int numberOfBuilds, Result threshol RunT r = getLastBuild(); return r.getBuildsOverThreshold(numberOfBuilds, threshold); } - + /** * Returns candidate build for calculating the estimated duration of the current run. - * + * * Returns the 3 last successful (stable or unstable) builds, if there are any. * Failing to find 3 of those, it will return up to 3 last unsuccessful builds. - * + * * In any case it will not go more than 6 builds into the past to avoid costly build loading. */ protected List getEstimatedDurationCandidates() { @@ -1037,20 +1036,20 @@ protected List getEstimatedDurationCandidates() { i++; r = r.getPreviousBuild(); } - + while (candidates.size() < 3) { if (fallbackCandidates.isEmpty()) break; RunT run = fallbackCandidates.remove(0); candidates.add(run); } - + return candidates; } - + public long getEstimatedDuration() { List builds = getEstimatedDurationCandidates(); - + if(builds.isEmpty()) return -1; long totalDuration = 0; @@ -1188,7 +1187,7 @@ public BallColor getIconColor() { /** * Get the current health report for a job. - * + * * @return the health report. Never returns null */ public HealthReport getBuildHealth() { @@ -1410,65 +1409,91 @@ public String getBuildStatusIconClassName() { return getIconColor().getIconClassName(); } - public Graph getBuildTimeGraph() { - return new Graph(getLastBuildTime(),500,400) { - @Override - protected JFreeChart createGraph() { - class ChartLabel implements Comparable { - final Run run; + private static class ChartLabel implements Comparable { + final Run run; - ChartLabel(Run r) { - this.run = r; - } + ChartLabel(Run r) { + this.run = r; + } - @Override - public int compareTo(ChartLabel that) { - return this.run.number - that.run.number; - } + @Override + public int compareTo(ChartLabel that) { + return this.run.number - that.run.number; + } - @Override - public boolean equals(Object o) { - // JENKINS-2682 workaround for Eclipse compilation bug - // on (c instanceof ChartLabel) - if (o == null || !ChartLabel.class.isAssignableFrom( o.getClass() )) { - return false; - } - ChartLabel that = (ChartLabel) o; - return run == that.run; - } + @Override + public boolean equals(Object o) { + // JENKINS-2682 workaround for Eclipse compilation bug + // on (c instanceof ChartLabel) + if (o == null || !ChartLabel.class.isAssignableFrom( o.getClass() )) { + return false; + } + ChartLabel that = (ChartLabel) o; + return run == that.run; + } - public Color getColor() { - // TODO: consider gradation. See - // http://www.javadrive.jp/java2d/shape/index9.html - Result r = run.getResult(); - if (r == Result.FAILURE) - return ColorPalette.RED; - else if (r == Result.UNSTABLE) - return ColorPalette.YELLOW; - else if (r == Result.ABORTED || r == Result.NOT_BUILT) - return ColorPalette.GREY; - else - return ColorPalette.BLUE; - } + public Color getColor() { + // TODO: consider gradation. See + // http://www.javadrive.jp/java2d/shape/index9.html + Result r = run.getResult(); + if (r == Result.FAILURE) + return ColorPalette.RED; + else if (r == Result.UNSTABLE) + return ColorPalette.YELLOW; + else if (r == Result.ABORTED || r == Result.NOT_BUILT) + return ColorPalette.GREY; + else + return ColorPalette.BLUE; + } - @Override - public int hashCode() { - return run.hashCode(); - } + @Override + public int hashCode() { + return run.hashCode(); + } - @Override - public String toString() { - String l = run.getDisplayName(); - if (run instanceof Build) { - String s = ((Build) run).getBuiltOnStr(); - if (s != null) - l += ' ' + s; - } - return l; - } + @Override + public String toString() { + String l = run.getDisplayName(); + if (run instanceof Build) { + String s = ((Build) run).getBuiltOnStr(); + if (s != null) + l += ' ' + s; + } + return l; + } + } - } + @SuppressFBWarnings(value = "EQ_DOESNT_OVERRIDE_EQUALS", justification = "category dataset is only relevant for coloring, not equality") + private static class ChartLabelStackedAreaRenderer2 extends StackedAreaRenderer2 { + private final CategoryDataset categoryDataset; + + ChartLabelStackedAreaRenderer2(CategoryDataset categoryDataset) { + this.categoryDataset = categoryDataset; + } + @Override + public Paint getItemPaint(int row, int column) { + ChartLabel key = (ChartLabel) categoryDataset.getColumnKey(column); + return key.getColor(); + } + + @Override + public String generateURL(CategoryDataset dataset, int row, int column) { + ChartLabel label = (ChartLabel) dataset.getColumnKey(column); + return String.valueOf(label.run.number); + } + + @Override + public String generateToolTip(CategoryDataset dataset, int row, int column) { + ChartLabel label = (ChartLabel) dataset.getColumnKey(column); + return label.run.getDisplayName() + " : " + label.run.getDurationString(); + } + } + + public Graph getBuildTimeGraph() { + return new Graph(getLastBuildTime(), 500, 400) { + @Override + protected JFreeChart createGraph() { DataSetBuilder data = new DataSetBuilder<>(); for (Run r : getNewBuilds()) { if (r.isBuilding()) @@ -1512,28 +1537,7 @@ public String toString() { ChartUtil.adjustChebyshev(dataset, rangeAxis); rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); - StackedAreaRenderer ar = new StackedAreaRenderer2() { - @Override - public Paint getItemPaint(int row, int column) { - ChartLabel key = (ChartLabel) dataset.getColumnKey(column); - return key.getColor(); - } - - @Override - public String generateURL(CategoryDataset dataset, int row, - int column) { - ChartLabel label = (ChartLabel) dataset.getColumnKey(column); - return String.valueOf(label.run.number); - } - - @Override - public String generateToolTip(CategoryDataset dataset, int row, - int column) { - ChartLabel label = (ChartLabel) dataset.getColumnKey(column); - return label.run.getDisplayName() + " : " - + label.run.getDurationString(); - } - }; + StackedAreaRenderer ar = new ChartLabelStackedAreaRenderer2(dataset); plot.setRenderer(ar); // crop extra space around the graph diff --git a/core/src/main/java/hudson/model/NoFingerprintMatch.java b/core/src/main/java/hudson/model/NoFingerprintMatch.java index 341773677600..d9063ab7401f 100644 --- a/core/src/main/java/hudson/model/NoFingerprintMatch.java +++ b/core/src/main/java/hudson/model/NoFingerprintMatch.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/hudson/model/PaneStatusProperties.java b/core/src/main/java/hudson/model/PaneStatusProperties.java index cad86b6e743a..29a460349440 100644 --- a/core/src/main/java/hudson/model/PaneStatusProperties.java +++ b/core/src/main/java/hudson/model/PaneStatusProperties.java @@ -10,84 +10,84 @@ import org.kohsuke.stapler.Stapler; public class PaneStatusProperties extends UserProperty implements Saveable { - - private final PersistedList collapsed = new PersistedList<>(this); - - private static final PaneStatusProperties FALLBACK = new PaneStatusPropertiesSessionFallback(); - - public boolean isCollapsed(String paneId) { - return collapsed.contains(paneId); - } - - /** - * @param paneId panel name - * @return the actual state of panel - */ - public boolean toggleCollapsed(String paneId) { - if (collapsed.contains(paneId)) { - collapsed.remove(paneId); - return false; - } else { - collapsed.add(paneId); - return true; - } - } - - @Override - public void save() throws IOException { + + private final PersistedList collapsed = new PersistedList<>(this); + + private static final PaneStatusProperties FALLBACK = new PaneStatusPropertiesSessionFallback(); + + public boolean isCollapsed(String paneId) { + return collapsed.contains(paneId); + } + + /** + * @param paneId panel name + * @return the actual state of panel + */ + public boolean toggleCollapsed(String paneId) { + if (collapsed.contains(paneId)) { + collapsed.remove(paneId); + return false; + } else { + collapsed.add(paneId); + return true; + } + } + + @Override + public void save() throws IOException { user.save(); } - - private Object readResolve() { - collapsed.setOwner(this); - return this; - } - - @Extension @Symbol("paneStatus") - public static class DescriptorImpl extends UserPropertyDescriptor { - - @Override - public UserProperty newInstance(User user) { - return new PaneStatusProperties(); - } - - @Override - public boolean isEnabled() { - return false; - } - - } - - private static class PaneStatusPropertiesSessionFallback extends PaneStatusProperties { - - private static final String attribute = "jenkins_pane_%s_collapsed"; - - @Override - public boolean isCollapsed(String paneId) { - final HttpSession session = Stapler.getCurrentRequest().getSession(); - return session.getAttribute(format(attribute, paneId)) != null; - } - - @Override - public boolean toggleCollapsed(String paneId) { - final HttpSession session = Stapler.getCurrentRequest().getSession(); - final String property = format(attribute, paneId); - final Object collapsed = session.getAttribute(property); - if (collapsed == null) { - session.setAttribute(property, true); - return true; - } - session.removeAttribute(property); - return false; - } - } - - public static PaneStatusProperties forCurrentUser() { - final User current = User.current(); - if (current == null) { - return FALLBACK; - } - return current.getProperty(PaneStatusProperties.class); - } + + private Object readResolve() { + collapsed.setOwner(this); + return this; + } + + @Extension @Symbol("paneStatus") + public static class DescriptorImpl extends UserPropertyDescriptor { + + @Override + public UserProperty newInstance(User user) { + return new PaneStatusProperties(); + } + + @Override + public boolean isEnabled() { + return false; + } + + } + + private static class PaneStatusPropertiesSessionFallback extends PaneStatusProperties { + + private static final String attribute = "jenkins_pane_%s_collapsed"; + + @Override + public boolean isCollapsed(String paneId) { + final HttpSession session = Stapler.getCurrentRequest().getSession(); + return session.getAttribute(format(attribute, paneId)) != null; + } + + @Override + public boolean toggleCollapsed(String paneId) { + final HttpSession session = Stapler.getCurrentRequest().getSession(); + final String property = format(attribute, paneId); + final Object collapsed = session.getAttribute(property); + if (collapsed == null) { + session.setAttribute(property, true); + return true; + } + session.removeAttribute(property); + return false; + } + } + + public static PaneStatusProperties forCurrentUser() { + final User current = User.current(); + if (current == null) { + return FALLBACK; + } + return current.getProperty(PaneStatusProperties.class); + } } diff --git a/core/src/main/java/hudson/model/ParametersDefinitionProperty.java b/core/src/main/java/hudson/model/ParametersDefinitionProperty.java index f08b067d29fb..7470330c7a01 100644 --- a/core/src/main/java/hudson/model/ParametersDefinitionProperty.java +++ b/core/src/main/java/hudson/model/ParametersDefinitionProperty.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Jean-Baptiste Quenot, Seiji Sogabe, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -142,7 +142,7 @@ public void _doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter Ti List values = new ArrayList<>(); - + JSONObject formData = req.getSubmittedForm(); JSONArray a = JSONArray.fromObject(formData.get("parameter")); @@ -161,7 +161,7 @@ public void _doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter Ti } } - WaitingItem item = Jenkins.get().getQueue().schedule( + WaitingItem item = Jenkins.get().getQueue().schedule( getJob(), delay.getTimeInSeconds(), new ParametersAction(values), new CauseAction(new Cause.UserIdCause())); if (item!=null) { String url = formData.optString("redirectTo"); @@ -182,10 +182,10 @@ public void buildWithParameters(StaplerRequest req, StaplerResponse rsp) throws public void buildWithParameters(StaplerRequest req, StaplerResponse rsp, @CheckForNull TimeDuration delay) throws IOException, ServletException { List values = new ArrayList<>(); for (ParameterDefinition d: parameterDefinitions) { - ParameterValue value = d.createValue(req); - if (value != null) { - values.add(value); - } + ParameterValue value = d.createValue(req); + if (value != null) { + values.add(value); + } } if (delay==null) delay=new TimeDuration(TimeUnit.MILLISECONDS.convert(getJob().getQuietPeriod(), TimeUnit.SECONDS)); @@ -193,7 +193,7 @@ public void buildWithParameters(StaplerRequest req, StaplerResponse rsp, @CheckF ScheduleResult scheduleResult = Jenkins.get().getQueue().schedule2( getJob(), delay.getTimeInSeconds(), new ParametersAction(values), ParameterizedJobMixIn.getBuildCause(getJob(), req)); Queue.Item item = scheduleResult.getItem(); - + if (item != null && !scheduleResult.isCreated()) { rsp.sendRedirect(SC_SEE_OTHER, req.getContextPath() + '/' + item.getUrl()); return; diff --git a/core/src/main/java/hudson/model/PeriodicWork.java b/core/src/main/java/hudson/model/PeriodicWork.java index c2fe69a61b6e..9a4e7279a9df 100644 --- a/core/src/main/java/hudson/model/PeriodicWork.java +++ b/core/src/main/java/hudson/model/PeriodicWork.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -53,7 +53,7 @@ * *

      * This class is designed to run a short task. Implementations whose periodic work takes a long time - * to run should extend from {@link AsyncPeriodicWork} instead. + * to run should extend from {@link AsyncPeriodicWork} instead. * * @author Kohsuke Kawaguchi * @see AsyncPeriodicWork diff --git a/core/src/main/java/hudson/model/Queue.java b/core/src/main/java/hudson/model/Queue.java index 82213ec77463..d0dbb990c87c 100644 --- a/core/src/main/java/hudson/model/Queue.java +++ b/core/src/main/java/hudson/model/Queue.java @@ -850,7 +850,7 @@ public StubItem[] getDiscoverableItems() { private List filterDiscoverableItemListBasedOnPermissions(List r, Item t) { if (t.task instanceof hudson.model.Item) { hudson.model.Item taskAsItem = (hudson.model.Item) t.task; - if (!taskAsItem.hasPermission(hudson.model.Item.READ) + if (!taskAsItem.hasPermission(hudson.model.Item.READ) && taskAsItem.hasPermission(hudson.model.Item.DISCOVER)) { r.add(new StubItem(new StubTask(t.task))); } @@ -947,7 +947,7 @@ public List getPendingItems() { protected List getBlockedItems() { return new ArrayList<>(snapshot.blockedProjects); } - + /** * Returns the snapshot of all {@link LeftItem}s. * @@ -1010,7 +1010,7 @@ public boolean isPending(Task t) { * @param l Label to be checked. If null, any label will be accepted. * If you want to count {@link BuildableItem}s without assigned labels, * use {@link #strictCountBuildableItemsFor(hudson.model.Label)}. - * @return Number of {@link BuildableItem}s for the specified label. + * @return Number of {@link BuildableItem}s for the specified label. */ public /* @java.annotation.Nonnegative */ int countBuildableItemsFor(@CheckForNull Label l) { Snapshot snapshot = this.snapshot; @@ -1025,7 +1025,7 @@ public boolean isPending(Task t) { r++; return r; } - + /** * How many {@link BuildableItem}s are assigned for the given label? *

      @@ -1331,7 +1331,7 @@ public static boolean tryWithLock(Runnable runnable) { } } /** - * Wraps a {@link Runnable} with the {@link Queue} lock held. + * Wraps a {@link Runnable} with the {@link Queue} lock held. * * @param runnable the operation to wrap. * @since 1.618 @@ -1344,7 +1344,7 @@ public static Runnable wrapWithLock(Runnable runnable) { } /** - * Wraps a {@link hudson.remoting.Callable} with the {@link Queue} lock held. + * Wraps a {@link hudson.remoting.Callable} with the {@link Queue} lock held. * * @param callable the operation to wrap. * @since 1.618 @@ -1357,7 +1357,7 @@ public static hudson.remoting.Callable wrapWithLo } /** - * Wraps a {@link java.util.concurrent.Callable} with the {@link Queue} lock held. + * Wraps a {@link java.util.concurrent.Callable} with the {@link Queue} lock held. * * @param callable the operation to wrap. * @since 1.618 @@ -1593,10 +1593,10 @@ public void maintain() { LOGGER.log(Level.WARNING, "s.sortBuildableItems() threw Throwable: {0}", e); } } - + // Ensure that identification of blocked tasks is using the live state: JENKINS-27708 & JENKINS-27871 updateSnapshot(); - + // allocate buildable jobs to executors for (BuildableItem p : new ArrayList<>( buildables)) {// copy as we'll mutate the list in the loop @@ -2217,7 +2217,7 @@ public Label getAssignedLabel() { * Test if the specified {@link SubTask} needs to be run on a node with a particular label. *

      * This method takes {@link LabelAssignmentAction} into account, the first - * non-null assignment will be returned. + * non-null assignment will be returned. * Otherwise falls back to {@link SubTask#getAssignedLabel()} * @param st {@link SubTask} to be checked. * @return Required {@link Label}. Otherwise null, indicating it can run on anywhere. @@ -2465,7 +2465,7 @@ public StubItem(StubTask task) { } } - + /** * An optional interface for actions on Queue.Item. * Lets the action cooperate in queue management. @@ -2987,7 +2987,7 @@ public String toString() { return "Queue.Snapshot{waitingList=" + waitingList + ";blockedProjects=" + blockedProjects + ";buildables=" + buildables + ";pendings=" + pendings + "}"; } } - + private static class LockedRunnable implements Runnable { private final Runnable delegate; diff --git a/core/src/main/java/hudson/model/ResourceActivity.java b/core/src/main/java/hudson/model/ResourceActivity.java index 978947d60e97..38511a7bd7ae 100644 --- a/core/src/main/java/hudson/model/ResourceActivity.java +++ b/core/src/main/java/hudson/model/ResourceActivity.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -41,12 +41,12 @@ public interface ResourceActivity { * If the activity doesn't lock any resources, just * return {@link ResourceList#EMPTY} (or decline to override). * - * @return never null + * @return never null */ default ResourceList getResourceList() { return ResourceList.EMPTY; } - + /** * Used for rendering HTML. */ diff --git a/core/src/main/java/hudson/model/Run.java b/core/src/main/java/hudson/model/Run.java index acb4455cb3c3..fa8500367c71 100644 --- a/core/src/main/java/hudson/model/Run.java +++ b/core/src/main/java/hudson/model/Run.java @@ -1,22 +1,22 @@ /* * The MIT License - * + * * Copyright (c) 2004-2012, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Daniel Dyer, Red Hat, Inc., Tom Huybrechts, Romain Seguy, Yahoo! Inc., * Darek Ostolski, CloudBees, Inc. * Copyright (c) 2012, Martin Schroeder, Intel Mobile Communications GmbH * Copyright (c) 2019 Intel Corporation - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -211,7 +211,7 @@ public abstract class Run ,RunT extends Run T getCause(Class type) { for (Cause c : getCauses()) if (type.isInstance(c)) @@ -628,7 +628,7 @@ public final boolean isKeepLog() { /** * If {@link #isKeepLog()} returns true, returns a short, human-readable * sentence that explains why it's being kept. - */ + */ public @CheckForNull String getWhyKeepLog() { if(keepLog) return Messages.Run_MarkedExplicitly(); @@ -637,7 +637,7 @@ public final boolean isKeepLog() { /** * The project this build is for. - */ + */ public @NonNull JobT getParent() { return project; } @@ -646,7 +646,7 @@ public final boolean isKeepLog() { * When the build is scheduled. * * @see #getStartTimeInMillis() - */ + */ @Exported public @NonNull Calendar getTimestamp() { GregorianCalendar c = new GregorianCalendar(); @@ -656,7 +656,7 @@ public final boolean isKeepLog() { /** * Same as {@link #getTimestamp()} but in a different type. - */ + */ public final @NonNull Date getTime() { return new Date(timestamp); } @@ -744,9 +744,9 @@ public String getDescription() { if (displayChars >= maxDescrLength) { truncDesc = truncDesc.substring(0, lastTruncatablePoint) + ending; } - + return truncDesc; - + } /** @@ -859,7 +859,7 @@ public int getNumber() { * @return Reference to the build. Never null * @see jenkins.model.lazy.LazyBuildMixIn.RunMixIn#createReference * @since 1.556 - */ + */ protected @NonNull BuildReference createReference() { return new BuildReference<>(getId(), _this()); } @@ -879,14 +879,14 @@ protected void dropLinks() { /** * @see jenkins.model.lazy.LazyBuildMixIn.RunMixIn#getPreviousBuild - */ + */ public @CheckForNull RunT getPreviousBuild() { return previousBuild; } /** * Gets the most recent {@linkplain #isBuilding() completed} build excluding 'this' Run itself. - */ + */ public final @CheckForNull RunT getPreviousCompletedBuild() { RunT r=getPreviousBuild(); while (r!=null && r.isBuilding()) @@ -901,7 +901,7 @@ protected void dropLinks() { *

      * We basically follow the existing skip list, and wherever we find a non-optimal pointer, we remember them * in 'fixUp' and update them later. - */ + */ public final @CheckForNull RunT getPreviousBuildInProgress() { if(previousBuildInProgress==this) return null; // the most common case @@ -937,7 +937,7 @@ protected void dropLinks() { /** * Returns the last build that was actually built - i.e., skipping any with Result.NOT_BUILT - */ + */ public @CheckForNull RunT getPreviousBuiltBuild() { RunT r=getPreviousBuild(); // in certain situations (aborted m2 builds) r.getResult() can still be null, although it should theoretically never happen @@ -948,7 +948,7 @@ protected void dropLinks() { /** * Returns the last build that didn't fail before this build. - */ + */ public @CheckForNull RunT getPreviousNotFailedBuild() { RunT r=getPreviousBuild(); while( r!=null && r.getResult()==Result.FAILURE ) @@ -958,7 +958,7 @@ protected void dropLinks() { /** * Returns the last failed build before this build. - */ + */ public @CheckForNull RunT getPreviousFailedBuild() { RunT r=getPreviousBuild(); while( r!=null && r.getResult()!=Result.FAILURE ) @@ -979,14 +979,14 @@ protected void dropLinks() { /** * Returns the last {@code numberOfBuilds} builds with a build result ≥ {@code threshold}. - * + * * @param numberOfBuilds the desired number of builds * @param threshold the build result threshold * @return a list with the builds (youngest build first). * May be smaller than 'numberOfBuilds' or even empty * if not enough builds satisfying the threshold have been found. Never null. * @since 1.383 - */ + */ public @NonNull List getPreviousBuildsOverThreshold(int numberOfBuilds, @NonNull Result threshold) { RunT r = getPreviousBuild(); if (r != null) { @@ -1022,7 +1022,7 @@ protected void dropLinks() { /** * @see jenkins.model.lazy.LazyBuildMixIn.RunMixIn#getNextBuild - */ + */ public @CheckForNull RunT getNextBuild() { return nextBuild; } @@ -1031,7 +1031,7 @@ protected void dropLinks() { * Returns the URL of this {@link Run}, relative to the context root of Hudson. * * @return - * String like "job/foo/32/" with trailing slash but no leading slash. + * String like "job/foo/32/" with trailing slash but no leading slash. */ // I really messed this up. I'm hoping to fix this some time // it shouldn't have trailing '/', and instead it should have leading '/' @@ -1079,7 +1079,7 @@ protected void dropLinks() { public @NonNull String getId() { return id != null ? id : Integer.toString(number); } - + /** * Get the root directory of this {@link Run} on the controller. * Files related to this {@link Run} should be stored below this directory. @@ -1144,8 +1144,8 @@ public File getArtifactsDir() { /** * Gets the artifacts (relative to {@link #getArtifactsDir()}. * @return The list can be empty but never null - */ - @Exported + */ + @Exported public @NonNull List getArtifacts() { return getArtifactsUpTo(Integer.MAX_VALUE); } @@ -1153,7 +1153,7 @@ public File getArtifactsDir() { /** * Gets the first N artifacts. * @return The list can be empty but never null - */ + */ public @NonNull List getArtifactsUpTo(int artifactsNumber) { SerializableArtifactList sal; VirtualFile root = getArtifactManager().root(); @@ -1195,7 +1195,7 @@ public SerializableArtifactList call() throws IOException { } private static int addArtifacts(@NonNull VirtualFile dir, - @NonNull String path, @NonNull String pathHref, + @NonNull String path, @NonNull String pathHref, @NonNull SerializableArtifactList r, @CheckForNull SerializableArtifact parent, int upTo) throws IOException { VirtualFile[] kids = dir.list(); Arrays.sort(kids); @@ -1232,7 +1232,7 @@ private static int addArtifacts(@NonNull VirtualFile dir, } return n; } - + /** * Maximum number of artifacts to list before using switching to the tree view. */ @@ -1244,7 +1244,7 @@ private static int addArtifacts(@NonNull VirtualFile dir, public static final int TREE_CUTOFF = Integer.parseInt(SystemProperties.getString("hudson.model.Run.ArtifactList.treeCutoff", "40")); // ..and then "too many" - + /** {@link Run.Artifact} without the implicit link to {@link Run} */ private static final class SerializableArtifact implements Serializable { private static final long serialVersionUID = 1L; @@ -1355,7 +1355,7 @@ public class Artifact { /** * Relative path name from artifacts root. */ - @Exported(visibility=3) + @Exported(visibility=3) public final String relativePath; /** @@ -1410,12 +1410,12 @@ public class Artifact { /** * Returns just the file name portion, without the path. */ - @Exported(visibility=3) + @Exported(visibility=3) public String getFileName() { return name; } - @Exported(visibility=3) + @Exported(visibility=3) public String getDisplayPath() { return displayPath; } @@ -1427,7 +1427,7 @@ public String getHref() { public String getLength() { return length; } - + public long getFileSize(){ try { return Long.decode(length); @@ -1462,7 +1462,7 @@ public Collection getBuildFingerprints() { } return Collections.emptyList(); } - + /** * Returns the log file. * @return The file may reference both uncompressed or compressed logs @@ -1487,15 +1487,15 @@ public Collection getBuildFingerprints() { * Returns an input stream that reads from the log file. * It will use a gzip-compressed log file (log.gz) if that exists. * - * @return An input stream from the log file. + * @return An input stream from the log file. * If the log file does not exist, the error message will be returned to the output. * @since 1.349 */ public @NonNull InputStream getLogInputStream() throws IOException { - File logFile = getLogFile(); - - if (logFile.exists() ) { - // Checking if a ".gz" file was return + File logFile = getLogFile(); + + if (logFile.exists() ) { + // Checking if a ".gz" file was return try { InputStream fis = Files.newInputStream(logFile.toPath()); if (logFile.getName().endsWith(".gz")) { @@ -1506,12 +1506,12 @@ public Collection getBuildFingerprints() { } catch (InvalidPathException e) { throw new IOException(e); } - } - + } + String message = "No such file: " + logFile; - return new ByteArrayInputStream(charset != null ? message.getBytes(charset) : message.getBytes(Charset.defaultCharset())); + return new ByteArrayInputStream(charset != null ? message.getBytes(charset) : message.getBytes(Charset.defaultCharset())); } - + public @NonNull Reader getLogReader() throws IOException { if (charset==null) return new InputStreamReader(getLogInputStream(),Charset.defaultCharset()); else return new InputStreamReader(getLogInputStream(),charset); @@ -1565,7 +1565,7 @@ public void writeWholeLogTo(@NonNull OutputStream out) throws IOException, Inter /** * Used to URL-bind {@link AnnotatedLargeText}. * @return A {@link Run} log with annotations - */ + */ public @NonNull AnnotatedLargeText getLogText() { return new AnnotatedLargeText(getLogFile(),getCharset(),!isLogUpdated(),this); } @@ -1593,7 +1593,7 @@ public ACL getACL() { } /** - * Deletes this build's artifacts. + * Deletes this build's artifacts. * * @throws IOException * if we fail to delete. @@ -1639,17 +1639,17 @@ public void delete() throws IOException { } return; } - + //The root dir exists and is a directory that needs to be purged RunListener.fireDeleted(this); - + if (artifactManager != null) { deleteArtifacts(); } // for StandardArtifactManager, deleting the whole build dir suffices - + synchronized (this) { // avoid holding a lock while calling plugin impls of onDeleted File tmp = new File(rootDir.getParentFile(),'.'+rootDir.getName()); - + if (tmp.exists()) { Util.deleteRecursive(tmp); } @@ -1662,7 +1662,7 @@ public void delete() throws IOException { } catch (UnsupportedOperationException | SecurityException ex) { throw new IOException(rootDir + " is in use", ex); } - + Util.deleteRecursive(tmp); // some user reported that they see some left-over .xyz files in the workspace, // so just to make sure we've really deleted it, schedule the deletion on VM exit, too. @@ -1728,7 +1728,7 @@ protected abstract class Runner extends RunExecution {} */ public abstract class RunExecution { /** - * Keeps track of the check points attained by a build, and abstracts away the synchronization needed to + * Keeps track of the check points attained by a build, and abstracts away the synchronization needed to * maintain this data structure. */ private final class CheckpointSet { @@ -2201,9 +2201,9 @@ public abstract static class StatusSummarizer implements ExtensionPoint { if (isBuilding()) { return new Summary(false, Messages.Run_Summary_Unknown()); } - + ResultTrend trend = ResultTrend.getResultTrend(this); - + for (StatusSummarizer summarizer : ExtensionList.lookup(StatusSummarizer.class)) { Summary summary = summarizer.summarize(this, trend); if (summary != null) { @@ -2213,30 +2213,30 @@ public abstract static class StatusSummarizer implements ExtensionPoint { switch (trend) { case ABORTED : return new Summary(false, Messages.Run_Summary_Aborted()); - + case NOT_BUILT : return new Summary(false, Messages.Run_Summary_NotBuilt()); - + case FAILURE : return new Summary(true, Messages.Run_Summary_BrokenSinceThisBuild()); - - case STILL_FAILING : + + case STILL_FAILING : RunT since = getPreviousNotFailedBuild(); if(since==null) return new Summary(false, Messages.Run_Summary_BrokenForALongTime()); RunT failedBuild = since.getNextBuild(); return new Summary(false, Messages.Run_Summary_BrokenSince(failedBuild.getDisplayName())); - + case NOW_UNSTABLE: case STILL_UNSTABLE : return new Summary(false, Messages.Run_Summary_Unstable()); case UNSTABLE : return new Summary(true, Messages.Run_Summary_Unstable()); - + case SUCCESS : return new Summary(false, Messages.Run_Summary_Stable()); - + case FIXED : return new Summary(false, Messages.Run_Summary_BackToNormal()); - + default: return new Summary(false, Messages.Run_Summary_Unknown()); } @@ -2356,7 +2356,7 @@ public void doDoDelete( StaplerRequest req, StaplerResponse rsp ) throws IOExcep } catch(IOException ex){ req.setAttribute("stackTraces", Functions.printThrowable(ex)); - req.getView(this, "delete-retry.jelly").forward(req, rsp); + req.getView(this, "delete-retry.jelly").forward(req, rsp); return; } rsp.sendRedirect2(req.getContextPath()+'/' + getParent().getUrl()); @@ -2367,7 +2367,7 @@ public void setDescription(String description) throws IOException { this.description = description; save(); } - + /** * Accepts the new description. */ @@ -2412,7 +2412,7 @@ public EnvVars getEnvironment() throws IOException, InterruptedException { *

      * Unlike earlier {@link #getEnvVars()}, this map contains the whole environment, * not just the overrides, so one can introspect values to change its behavior. - * + * * @return the map with the environmental variables. * @since 1.305 */ @@ -2491,7 +2491,7 @@ public EnvVars getEnvironment() throws IOException, InterruptedException { * Returns the estimated duration for this run if it is currently running. * Default to {@link Job#getEstimatedDuration()}, may be overridden in subclasses * if duration may depend on run specific parameters (like incremental Maven builds). - * + * * @return the estimated duration in milliseconds * @since 1.383 */ @@ -2531,7 +2531,7 @@ protected void submit(JSONObject json) throws IOException { private static final Logger LOGGER = Logger.getLogger(Run.class.getName()); /** - * Sort by date. Newer ones first. + * Sort by date. Newer ones first. */ public static final Comparator ORDER_BY_DATE = new Comparator() { @Override diff --git a/core/src/main/java/hudson/model/RunMap.java b/core/src/main/java/hudson/model/RunMap.java index 451fd577f584..88f8da4f8127 100644 --- a/core/src/main/java/hudson/model/RunMap.java +++ b/core/src/main/java/hudson/model/RunMap.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/hudson/model/UpdateCenter.java b/core/src/main/java/hudson/model/UpdateCenter.java index 56b45ca4debf..2a9302b9081e 100644 --- a/core/src/main/java/hudson/model/UpdateCenter.java +++ b/core/src/main/java/hudson/model/UpdateCenter.java @@ -142,13 +142,13 @@ *

      * Extending Update Centers. The update center in {@code Jenkins} can be replaced by defining a * System Property ({@code hudson.model.UpdateCenter.className}). See {@link #createUpdateCenter(hudson.model.UpdateCenter.UpdateCenterConfiguration)}. - * This className should be available on early startup, so it cannot come only from a library + * This className should be available on early startup, so it cannot come only from a library * (e.g. Jenkins module or Extra library dependency in the WAR file project). * Plugins cannot be used for such purpose. - * In order to be correctly instantiated, the class definition must have two constructors: + * In order to be correctly instantiated, the class definition must have two constructors: * {@link #UpdateCenter()} and {@link #UpdateCenter(hudson.model.UpdateCenter.UpdateCenterConfiguration)}. * If the class does not comply with the requirements, a fallback to the default UpdateCenter will be performed. - * + * * @author Kohsuke Kawaguchi * @since 1.220 */ @@ -268,7 +268,7 @@ public UpdateCenter() { UpdateCenter(@NonNull UpdateCenterConfiguration configuration) { configure(configuration); } - + /** * Creates an update center. * @param config Requested configuration. May be {@code null} if defaults should be used @@ -283,7 +283,7 @@ public static UpdateCenter createUpdateCenter(@CheckForNull UpdateCenterConfigur LOGGER.log(Level.FINE, "Using the default Update Center implementation"); return createDefaultUpdateCenter(config); } - + LOGGER.log(Level.FINE, "Using the custom update center: {0}", requiredClassName); try { final Class clazz = Class.forName(requiredClassName).asSubclass(UpdateCenter.class); @@ -308,7 +308,7 @@ public static UpdateCenter createUpdateCenter(@CheckForNull UpdateCenterConfigur } return createDefaultUpdateCenter(config); } - + @NonNull private static UpdateCenter createDefaultUpdateCenter(@CheckForNull UpdateCenterConfiguration config) { return config != null ? new UpdateCenter(config) : new UpdateCenter(); @@ -695,9 +695,9 @@ public String getDefaultBaseUrl() { private boolean checkMinVersion(@CheckForNull Plugin p, @CheckForNull VersionNumber minVersion) { return p != null && (minVersion == null || !minVersion.isNewerThan(new VersionNumber(p.version))); - } + } - /** + /** * Schedules a Jenkins upgrade. */ @RequirePOST @@ -1663,7 +1663,7 @@ public void run() { addStatus(e); error = e; } - + if(internetCheck != null) { try { // Wait for internet check to complete @@ -1686,7 +1686,7 @@ public String[] getStatuses() { } - + /** * Enables a required plugin, provides feedback in the update center */ @@ -1694,11 +1694,11 @@ public class EnableJob extends InstallationJob { public EnableJob(UpdateSite site, Authentication auth, @NonNull Plugin plugin, boolean dynamicLoad) { super(plugin, site, auth, dynamicLoad); } - + public Plugin getPlugin() { return plugin; } - + @Override public void run() { try { @@ -1712,7 +1712,7 @@ public void run() { error = e; status = new DownloadJob.Failure(e); } - + if (dynamicLoad) { try { // remove the existing, disabled inactive plugin to force a new one to load @@ -1739,7 +1739,7 @@ public void run() { } } } - + /** * A no-op, e.g. this plugin is already installed */ @@ -1760,7 +1760,7 @@ public void run() { String getComputedSHA256(); String getComputedSHA512(); } - + /** * Base class for a job that downloads a file from the Jenkins project. */ diff --git a/core/src/main/java/hudson/model/UpdateSite.java b/core/src/main/java/hudson/model/UpdateSite.java index cf56d13bea44..53865761eb16 100644 --- a/core/src/main/java/hudson/model/UpdateSite.java +++ b/core/src/main/java/hudson/model/UpdateSite.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Yahoo! Inc., Seiji Sogabe, * Andrew Bayer - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -219,7 +219,7 @@ public long getDataTimestamp() { public @NonNull FormValidation updateDirectlyNow(boolean signatureCheck) throws IOException { return updateData(DownloadService.loadJSON(new URL(getUrl() + "?id=" + URLEncoder.encode(getId(), "UTF-8") + "&version=" + URLEncoder.encode(Jenkins.VERSION, "UTF-8"))), signatureCheck); } - + private FormValidation updateData(String json, boolean signatureCheck) throws IOException { @@ -314,7 +314,7 @@ public synchronized boolean isDue() { long now = System.currentTimeMillis(); retryWindow = Math.max(retryWindow,SECONDS.toMillis(15)); - + boolean due = now - dataTimestamp > DAY && now - lastAttempt > retryWindow; if(due) { lastAttempt = now; @@ -447,7 +447,7 @@ private TextFile getDataFile() { return new TextFile(new File(Jenkins.get().getRootDir(), "updates/" + getId()+".json")); } - + /** * Returns the list of plugins that are updates to currently installed ones. * @@ -458,16 +458,16 @@ private TextFile getDataFile() { public List getUpdates() { Data data = getData(); if(data==null) return Collections.emptyList(); // fail to determine - + List r = new ArrayList<>(); for (PluginWrapper pw : Jenkins.get().getPluginManager().getPlugins()) { Plugin p = pw.getUpdateInfo(); if(p!=null) r.add(p); } - + return r; } - + /** * Does any of the plugin has updates? */ @@ -475,17 +475,17 @@ public List getUpdates() { public boolean hasUpdates() { Data data = getData(); if(data==null) return false; - + for (PluginWrapper pw : Jenkins.get().getPluginManager().getPlugins()) { if(!pw.isBundled() && pw.getUpdateInfo()!=null) // do not advertize updates to bundled plugins, since we generally want users to get them - // as a part of jenkins.war updates. This also avoids unnecessary pinning of plugins. + // as a part of jenkins.war updates. This also avoids unnecessary pinning of plugins. return true; } return false; } - - + + /** * Exposed to get rid of hardcoding of the URL that serves up update-center.json * in JavaScript. @@ -1164,7 +1164,7 @@ public final class Plugin extends Entry { */ @Exported public final Map dependencies; - + /** * Optional dependencies of this plugin. */ diff --git a/core/src/main/java/hudson/model/UsageStatistics.java b/core/src/main/java/hudson/model/UsageStatistics.java index a62031bfc406..1b57d7282403 100644 --- a/core/src/main/java/hudson/model/UsageStatistics.java +++ b/core/src/main/java/hudson/model/UsageStatistics.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -73,7 +73,7 @@ @Extension public class UsageStatistics extends PageDecorator implements PersistentDescriptor { private static final Logger LOG = Logger.getLogger(UsageStatistics.class.getName()); - + private final String keyImage; /** @@ -103,7 +103,7 @@ public UsageStatistics(String keyImage) { public boolean isDue() { // user opted out. no data collection. if(!Jenkins.get().isUsageStatisticsCollected() || DISABLED) return false; - + long now = System.currentTimeMillis(); if(now - lastAttempt > DAY) { lastAttempt = now; @@ -125,7 +125,7 @@ private RSAPublicKey getKey() { } /** - * Gets the encrypted usage stat data to be sent to the Hudson server. + * Gets the encrypted usage stat data to be sent to the Hudson server. * Used exclusively by jelly: resources/hudson/model/UsageStatistics/footer.jelly */ public String getStatData() throws IOException { diff --git a/core/src/main/java/hudson/model/UserPropertyDescriptor.java b/core/src/main/java/hudson/model/UserPropertyDescriptor.java index 5367c7c01451..a29ab777c880 100644 --- a/core/src/main/java/hudson/model/UserPropertyDescriptor.java +++ b/core/src/main/java/hudson/model/UserPropertyDescriptor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Daniel Dyer - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,7 +25,7 @@ /** * {@link Descriptor} for {@link UserProperty}. - * + * * @author Kohsuke Kawaguchi */ public abstract class UserPropertyDescriptor extends Descriptor { @@ -67,7 +67,7 @@ protected UserPropertyDescriptor() { * *

      * This mechanism is useful if the availability of the property is - * contingent of some other settings. + * contingent of some other settings. */ public boolean isEnabled() { return true; diff --git a/core/src/main/java/hudson/model/View.java b/core/src/main/java/hudson/model/View.java index 9b0160f4de02..b743d91834e4 100644 --- a/core/src/main/java/hudson/model/View.java +++ b/core/src/main/java/hudson/model/View.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts, * Yahoo!, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -105,7 +105,6 @@ import net.sf.json.JSON; import net.sf.json.JSONArray; import net.sf.json.JSONObject; -import org.apache.commons.jelly.JellyContext; import org.apache.commons.lang.StringUtils; import org.jenkins.ui.icon.Icon; import org.jenkins.ui.icon.IconSet; @@ -139,7 +138,7 @@ *

    • * {@link View} subtypes need the {@code newViewDetail.jelly} page, * which is included in the "new view" page. This page should have some - * description of what the view is about. + * description of what the view is about. *
    * * @author Kohsuke Kawaguchi @@ -164,7 +163,7 @@ public abstract class View extends AbstractModelObject implements AccessControll * Message displayed in the view page. */ protected String description; - + /** * If true, only show relevant executors */ @@ -174,7 +173,7 @@ public abstract class View extends AbstractModelObject implements AccessControll * If true, only show relevant queue items */ protected boolean filterQueue; - + /** * List of {@link ViewProperty}s configured for this view. * @since 1.406 @@ -385,7 +384,7 @@ public String getNewPronoun() { public boolean isEditable() { return true; } - + /** * Used to enable or disable automatic refreshes of the view. * @@ -397,14 +396,14 @@ public boolean isEditable() { public boolean isAutomaticRefreshEnabled() { return false; } - + /** * If true, only show relevant executors */ public boolean isFilterExecutors() { return filterExecutors; } - + /** * If true, only show relevant queue items */ @@ -443,7 +442,7 @@ public Indenter getIndenter() { public boolean isDefault() { return getOwner().getPrimaryView()==this; } - + public List getComputers() { Computer[] computers = Jenkins.get().getComputers(); @@ -958,13 +957,13 @@ public final class People { void addDisplayNamesToSearchIndex(SearchIndexBuilder sib, Collection items) { for(TopLevelItem item : items) { - + if(LOGGER.isLoggable(Level.FINE)) { LOGGER.fine(String.format("Adding url=%s,displayName=%s", item.getSearchUrl(), item.getDisplayName())); } sib.add(item.getSearchUrl(), item.getDisplayName()); - } + } } /** @@ -991,7 +990,7 @@ protected String getName(TopLevelItem o) { public SearchIndexBuilder makeSearchIndex() { SearchIndexBuilder sib = super.makeSearchIndex(); makeSearchIndex(sib); - + // add the display name for each item in the search index addDisplayNamesToSearchIndex(sib, getItems()); @@ -1060,7 +1059,7 @@ public synchronized void doDoDelete(StaplerRequest req, StaplerResponse rsp) thr *

    * This method should call {@link ModifiableItemGroup#doCreateItem(StaplerRequest, StaplerResponse)} * and then add the newly created item to this view. - * + * * @return * null if fails. */ @@ -1110,13 +1109,12 @@ public Categories doItemCategories(StaplerRequest req, StaplerResponse rsp, @Que rsp.addHeader("Expires", "0"); Categories categories = new Categories(); int order = 0; - JellyContext ctx; + String resUrl; if (StringUtils.isNotBlank(iconStyle)) { - ctx = new JellyContext(); - ctx.setVariable("resURL", req.getContextPath() + Jenkins.RESOURCE_PATH); + resUrl = req.getContextPath() + Jenkins.RESOURCE_PATH; } else { - ctx = null; + resUrl = null; } for (TopLevelItemDescriptor descriptor : DescriptorVisibilityFilter.apply(getOwner().getItemGroup(), Items.all2(Jenkins.getAuthentication2(), getOwner().getItemGroup()))) { ItemCategory ic = ItemCategory.getCategory(descriptor); @@ -1131,11 +1129,11 @@ public Categories doItemCategories(StaplerRequest req, StaplerResponse rsp, @Que String iconClassName = descriptor.getIconClassName(); if (StringUtils.isNotBlank(iconClassName)) { metadata.put("iconClassName", iconClassName); - if (ctx != null) { + if (resUrl != null) { Icon icon = IconSet.icons .getIconByClassSpec(String.join(" ", iconClassName, iconStyle)); if (icon != null) { - metadata.put("iconQualifiedUrl", icon.getQualifiedUrl(ctx)); + metadata.put("iconQualifiedUrl", icon.getQualifiedUrl(resUrl)); } } } @@ -1160,11 +1158,11 @@ public void doRssAll( StaplerRequest req, StaplerResponse rsp ) throws IOExcepti public void doRssFailed( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().failureOnly().newBuilds()); } - + public RunList getBuilds() { return new RunList(this); } - + public BuildTimelineWidget getTimeline() { return new BuildTimelineWidget(getBuilds()); } @@ -1336,7 +1334,7 @@ public static void registerPermissions() { public static Permission getItemCreatePermission() { return Item.CREATE; } - + public static View create(StaplerRequest req, StaplerResponse rsp, ViewGroup owner) throws FormException, IOException, ServletException { String mode = req.getParameter("mode"); diff --git a/core/src/main/java/hudson/model/queue/MappingWorksheet.java b/core/src/main/java/hudson/model/queue/MappingWorksheet.java index 02492a81f675..f6f5edb35df9 100644 --- a/core/src/main/java/hudson/model/queue/MappingWorksheet.java +++ b/core/src/main/java/hudson/model/queue/MappingWorksheet.java @@ -314,7 +314,7 @@ public MappingWorksheet(BuildableItem item, List offers) public MappingWorksheet(BuildableItem item, List offers, Collection loadPredictors) { this.item = item; - + // group executors by their computers Map> j = new HashMap<>(); for (ExecutorSlot o : offers) { diff --git a/core/src/main/java/hudson/os/SU.java b/core/src/main/java/hudson/os/SU.java index 9103c72a866f..6a373cd53e04 100644 --- a/core/src/main/java/hudson/os/SU.java +++ b/core/src/main/java/hudson/os/SU.java @@ -159,7 +159,7 @@ VirtualChannel start(TaskListener listener, String rootPassword) throws IOExcept ArgumentListBuilder args = new ArgumentListBuilder().add(javaExe); if(agentJar.isFile()) args.add("-jar").add(agentJar); - else // in production code this never happens, but during debugging this is convenient + else // in production code this never happens, but during debugging this is convenient args.add("-cp").add(agentJar).add(hudson.remoting.Launcher.class.getName()); if (Util.fixEmptyAndTrim(rootPassword) == null) { diff --git a/core/src/main/java/hudson/scheduler/CronTab.java b/core/src/main/java/hudson/scheduler/CronTab.java index c01f74e167aa..9055912cc3ca 100644 --- a/core/src/main/java/hudson/scheduler/CronTab.java +++ b/core/src/main/java/hudson/scheduler/CronTab.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, InfraDNA, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -62,7 +62,7 @@ public final class CronTab { private String spec; /** - * Optional timezone string for calendar + * Optional timezone string for calendar */ private @CheckForNull String specTimezone; @@ -73,7 +73,7 @@ public CronTab(String format) throws ANTLRException { public CronTab(String format, Hash hash) throws ANTLRException { this(format,1,hash); } - + /** * @deprecated as of 1.448 * Use {@link #CronTab(String, int, Hash)} @@ -94,14 +94,14 @@ public CronTab(String format, int line, Hash hash) throws ANTLRException { /** * @param timezone - * Used to schedule cron in a different timezone. Null to use the default system + * Used to schedule cron in a different timezone. Null to use the default system * timezone * @since 1.615 */ public CronTab(String format, int line, Hash hash, @CheckForNull String timezone) throws ANTLRException { set(format, line, hash, timezone); } - + private void set(String format, int line, Hash hash) throws ANTLRException { set(format, line, hash, null); } diff --git a/core/src/main/java/hudson/scm/SCMDescriptor.java b/core/src/main/java/hudson/scm/SCMDescriptor.java index 7a9465b88e06..f7d61f1f7323 100644 --- a/core/src/main/java/hudson/scm/SCMDescriptor.java +++ b/core/src/main/java/hudson/scm/SCMDescriptor.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -52,7 +52,7 @@ public abstract class SCMDescriptor extends Descriptor { * that type. Otherwise this SCM will not have any repository browser. */ public final transient Class repositoryBrowser; - + private final transient AtomicInteger atomicGeneration = new AtomicInteger(1); protected SCMDescriptor(Class clazz, Class repositoryBrowser) { diff --git a/core/src/main/java/hudson/scm/browsers/QueryBuilder.java b/core/src/main/java/hudson/scm/browsers/QueryBuilder.java index f80ca8a8068e..04dffed3e15c 100644 --- a/core/src/main/java/hudson/scm/browsers/QueryBuilder.java +++ b/core/src/main/java/hudson/scm/browsers/QueryBuilder.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/hudson/search/QuickSilver.java b/core/src/main/java/hudson/search/QuickSilver.java index 0d78712dc33e..43d71b9a61bd 100644 --- a/core/src/main/java/hudson/search/QuickSilver.java +++ b/core/src/main/java/hudson/search/QuickSilver.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -43,7 +43,7 @@ *

    * Such getter/field indicates an edge in the search graph, and will be added * automatically by {@link SearchIndexBuilder#addAllAnnotations(SearchableModelObject)} - * to a search index. + * to a search index. * * @author Kohsuke Kawaguchi */ diff --git a/core/src/main/java/hudson/search/Search.java b/core/src/main/java/hudson/search/Search.java index 94bc989dac21..37971a7ee731 100644 --- a/core/src/main/java/hudson/search/Search.java +++ b/core/src/main/java/hudson/search/Search.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi, * Yahoo!, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -133,7 +133,7 @@ public void doSuggest(StaplerRequest req, StaplerResponse rsp, @QueryParameter S * * @return * can be empty but never null. The size of the list is always smaller than - * a certain threshold to avoid showing too many options. + * a certain threshold to avoid showing too many options. */ public SearchResult getSuggestions(StaplerRequest req, String query) { Set paths = new HashSet<>(); // paths already added, to control duplicates @@ -225,7 +225,7 @@ void find(SearchIndex index, String token, List result) { * When there are multiple suggested items, this method can narrow down the resultset * to the SuggestedItem that has a url that contains the query. This is useful is one * job has a display name that matches another job's project name. - * @param r A list of Suggested items. It is assumed that there is at least one + * @param r A list of Suggested items. It is assumed that there is at least one * SuggestedItem in r. * @param query A query string * @return Returns the SuggestedItem which has a search url that contains the query. @@ -241,12 +241,12 @@ static SuggestedItem findClosestSuggestedItem(List r, String quer return curItem; } } - + // couldn't find an item with the query in the url so just // return the first one - return r.get(0); + return r.get(0); } - + /** * @deprecated Use {@link Search#find(SearchIndex, String, SearchableModelObject)} instead. */ @@ -254,7 +254,7 @@ static SuggestedItem findClosestSuggestedItem(List r, String quer public static SuggestedItem find(SearchIndex index, String query) { return find(index, query, null); } - + /** * Performs a search and returns the match, or null if no match was found * or more than one match was found. @@ -262,7 +262,7 @@ public static SuggestedItem find(SearchIndex index, String query) { */ public static SuggestedItem find(SearchIndex index, String query, SearchableModelObject searchContext) { List r = find(Mode.FIND, index, query, searchContext); - if(r.isEmpty()){ + if(r.isEmpty()){ return null; } else if(1==r.size()){ @@ -273,11 +273,11 @@ else if(1==r.size()){ // contains the query as this is probably the job's name return findClosestSuggestedItem(r, query); } - + } /** - * @deprecated use {@link Search#suggest(SearchIndex, String, SearchableModelObject)} instead. + * @deprecated use {@link Search#suggest(SearchIndex, String, SearchableModelObject)} instead. */ @Deprecated public static List suggest(SearchIndex index, final String tokenList) { @@ -301,7 +301,6 @@ class Tag implements Comparable{ prefixMatch = i.getPath().startsWith(tokenList)?1:0; } - @SuppressFBWarnings(value = "EQ_COMPARETO_USE_OBJECT_EQUALS", justification = "TODO needs triage") @Override public int compareTo(Tag that) { int r = this.prefixMatch -that.prefixMatch; @@ -354,8 +353,8 @@ public int size() { } }; } - - + + @Override public String toString() { StringBuilder s = new StringBuilder("TokenList{"); @@ -364,7 +363,7 @@ public String toString() { s.append(","); } s.append('}'); - + return s.toString(); } } @@ -380,7 +379,7 @@ private static List find(Mode m, SearchIndex index, String tokenL List items = new ArrayList<>(); // items found in 1 step LOGGER.log(Level.FINE, "tokens={0}", tokens); - + // first token int w=1; // width of token for (String token : tokens.subSequence(0)) { diff --git a/core/src/main/java/hudson/search/SearchItems.java b/core/src/main/java/hudson/search/SearchItems.java index 9edc46fd541b..0f9a2d63dd3d 100644 --- a/core/src/main/java/hudson/search/SearchItems.java +++ b/core/src/main/java/hudson/search/SearchItems.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/hudson/security/BasicAuthenticationFilter.java b/core/src/main/java/hudson/security/BasicAuthenticationFilter.java index d481260c3a4a..5fd45efb0bb6 100644 --- a/core/src/main/java/hudson/security/BasicAuthenticationFilter.java +++ b/core/src/main/java/hudson/security/BasicAuthenticationFilter.java @@ -98,7 +98,6 @@ public void init(FilterConfig filterConfig) throws ServletException { } @Override - @SuppressWarnings("ACL.impersonate") public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse rsp = (HttpServletResponse) response; diff --git a/core/src/main/java/hudson/security/FederatedLoginService.java b/core/src/main/java/hudson/security/FederatedLoginService.java index 036332c8c7ce..be1efda827a7 100644 --- a/core/src/main/java/hudson/security/FederatedLoginService.java +++ b/core/src/main/java/hudson/security/FederatedLoginService.java @@ -182,7 +182,6 @@ public final User locateUser() { * to the caller of your "doXyz" method, it will either render an error page or initiate * a user registration session (provided that {@link SecurityRealm} supports that.) */ - @SuppressWarnings("ACL.impersonate") @NonNull public User signin() throws UnclaimedIdentityException { User u = locateUser(); diff --git a/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java b/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java index 3acab22bf065..bc9e9a01b70d 100644 --- a/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java +++ b/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -54,7 +54,7 @@ * *

    * The page that programs see is entirely white, and it auto-redirects, - * so humans wouldn't notice it. + * so humans wouldn't notice it. * * @author Kohsuke Kawaguchi */ diff --git a/core/src/main/java/hudson/security/HudsonFilter.java b/core/src/main/java/hudson/security/HudsonFilter.java index fe08768f9d5e..74e48959f983 100644 --- a/core/src/main/java/hudson/security/HudsonFilter.java +++ b/core/src/main/java/hudson/security/HudsonFilter.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -56,7 +56,7 @@ public class HudsonFilter implements Filter { * The SecurityRealm specific filter. */ private volatile Filter filter; - + /** * The {@link #init(FilterConfig)} may be called before the Jenkins instance is up (which is * required for initialization of the filter). So we store the @@ -85,7 +85,7 @@ public class HudsonFilter implements Filter { */ @Deprecated public static final UserDetailsServiceProxy USER_DETAILS_SERVICE_PROXY = new UserDetailsServiceProxy(); - + /** * {@link RememberMeServices} proxy so that the Spring Security filter chain can stay the same * even when security setting is reconfigured. diff --git a/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java b/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java index 7c46a1bc65bc..d01449d38163 100644 --- a/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java +++ b/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java @@ -105,14 +105,14 @@ */ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRealm implements ModelObject, AccessControlled { private static /* not final */ String ID_REGEX = System.getProperty(HudsonPrivateSecurityRealm.class.getName() + ".ID_REGEX"); - + /** * Default REGEX for the user ID check in case the ID_REGEX is not set * It allows A-Za-z0-9 + "_-" * in Java {@code \w} is equivalent to {@code [A-Za-z0-9_]} (take care of "_") */ private static final String DEFAULT_ID_REGEX = "^[\\w-]+$"; - + /** * If true, sign up is not allowed. *

    @@ -268,7 +268,6 @@ private User _doCreateAccount(StaplerRequest req, StaplerResponse rsp, String fo /** * Lets the current user silently login as the given user and report back accordingly. */ - @SuppressWarnings("ACL.impersonate") private void loginAndTakeBack(StaplerRequest req, StaplerResponse rsp, User u) throws ServletException, IOException { HttpSession session = req.getSession(false); if (session != null) { @@ -276,7 +275,7 @@ private void loginAndTakeBack(StaplerRequest req, StaplerResponse rsp, User u) t session.invalidate(); } req.getSession(true); - + // ... and let him login Authentication a = new UsernamePasswordAuthenticationToken(u.getId(),req.getParameter("password1")); a = this.getSecurityComponents().manager2.authenticate(a); diff --git a/core/src/main/java/hudson/security/SecurityMode.java b/core/src/main/java/hudson/security/SecurityMode.java index 6119cd04e3ef..bcfa0b82919c 100644 --- a/core/src/main/java/hudson/security/SecurityMode.java +++ b/core/src/main/java/hudson/security/SecurityMode.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -30,7 +30,7 @@ */ public enum SecurityMode { /** - * None. Anyone can make any changes. + * None. Anyone can make any changes. */ UNSECURED, /** @@ -41,7 +41,7 @@ public enum SecurityMode { * Authentication is performed by the container. *

    * This is the only secured mode of Hudson up to 1.160. - * This is maintained only for backward compatibility. + * This is maintained only for backward compatibility. */ LEGACY, /** diff --git a/core/src/main/java/hudson/security/SidACL.java b/core/src/main/java/hudson/security/SidACL.java index 870781031953..df8b375f7e46 100644 --- a/core/src/main/java/hudson/security/SidACL.java +++ b/core/src/main/java/hudson/security/SidACL.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -114,7 +114,7 @@ protected Boolean _hasPermission(@NonNull Authentication a, Permission permissio * true if the access should be granted, false if it should be denied. * The null value indicates that the ACL does no rule for this Sid/Permission * combination. The caller can decide what to do—such as consulting the higher level ACL, - * or denying the access (if the model is no-access-by-default.) + * or denying the access (if the model is no-access-by-default.) */ protected abstract Boolean hasPermission(Sid p, Permission permission); diff --git a/core/src/main/java/hudson/security/SparseACL.java b/core/src/main/java/hudson/security/SparseACL.java index 1ba755049391..ad8f4d2e7a89 100644 --- a/core/src/main/java/hudson/security/SparseACL.java +++ b/core/src/main/java/hudson/security/SparseACL.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/hudson/slaves/SlaveComputer.java b/core/src/main/java/hudson/slaves/SlaveComputer.java index b5dc5eaff3e9..df915a0bf1ea 100644 --- a/core/src/main/java/hudson/slaves/SlaveComputer.java +++ b/core/src/main/java/hudson/slaves/SlaveComputer.java @@ -226,11 +226,11 @@ public TaskListener getListener() { } @Override - public String getIcon() { + public String getIconClassName() { Future l = lastConnectActivity; if(l!=null && !l.isDone()) - return "computer-flash.gif"; - return super.getIcon(); + return "icon-computer-flash"; + return super.getIconClassName(); } /** diff --git a/core/src/main/java/hudson/tasks/LogRotator.java b/core/src/main/java/hudson/tasks/LogRotator.java index 89ba0cf3a9c4..996f35d382c3 100644 --- a/core/src/main/java/hudson/tasks/LogRotator.java +++ b/core/src/main/java/hudson/tasks/LogRotator.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt * Copyright (c) 2019 Intel Corporation - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -53,20 +53,20 @@ * Default implementation of {@link BuildDiscarder}. * * For historical reason, this is called LogRotator, but it does not rotate logs :-) - * + * * Since 1.350 it has also the option to keep the build, but delete its recorded artifacts. - * + * * @author Kohsuke Kawaguchi */ public class LogRotator extends BuildDiscarder { - + /** @deprecated Replaced by more generic {@link CompositeIOException}. */ @Deprecated public static class CollatedLogRotatorException extends IOException { private static final long serialVersionUID = 5944233808072651101L; - + public final Collection collated; - + public CollatedLogRotatorException(String msg, Exception... collated) { super(msg); if (collated == null || collated.length == 0) { @@ -81,7 +81,7 @@ public CollatedLogRotatorException(String msg, Collection values) { this.collated = values != null ? values : Collections.emptyList(); } } - + /** * If not -1, history is only kept up to this days. */ @@ -135,17 +135,17 @@ public LogRotator(int daysToKeep, int numToKeep, int artifactDaysToKeep, int art this.numToKeep = numToKeep; this.artifactDaysToKeep = artifactDaysToKeep; this.artifactNumToKeep = artifactNumToKeep; - + } - + @Override @SuppressWarnings("rawtypes") public void perform(Job job) throws IOException, InterruptedException { //Exceptions thrown by the deletion submethods are collated and reported Map, Set> exceptionMap = new HashMap<>(); - + LOGGER.log(FINE, "Running the log rotation for {0} with numToKeep={1} daysToKeep={2} artifactNumToKeep={3} artifactDaysToKeep={4}", new Object[] {job, numToKeep, daysToKeep, artifactNumToKeep, artifactDaysToKeep}); - + // always keep the last successful and the last stable builds Run lsb = job.getLastSuccessfulBuild(); Run lstb = job.getLastStableBuild(); @@ -212,7 +212,7 @@ public void perform(Job job) throws IOException, InterruptedException { r = r.getNextBuild(); } } - + if (!exceptionMap.isEmpty()) { //Collate all encountered exceptions into a single exception and throw that String msg = String.format( diff --git a/core/src/main/java/hudson/triggers/SCMTrigger.java b/core/src/main/java/hudson/triggers/SCMTrigger.java index 05b3fa1ea5fe..7d3d5e285cae 100644 --- a/core/src/main/java/hudson/triggers/SCMTrigger.java +++ b/core/src/main/java/hudson/triggers/SCMTrigger.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Brian Westrich, Jean-Baptiste Quenot, id:cactusman * 2015 Kanstantsin Shautsou - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -96,14 +96,14 @@ * * You can add UI elements under the SCM section by creating a * config.jelly or config.groovy in the resources area for - * your class that inherits from SCMTrigger and has the - * {@link Extension} annotation. The UI should + * your class that inherits from SCMTrigger and has the + * {@link Extension} annotation. The UI should * be wrapped in an f:section element to denote it. * * @author Kohsuke Kawaguchi */ public class SCMTrigger extends Trigger { - + private boolean ignorePostCommitHooks; @DataBoundConstructor @@ -131,7 +131,7 @@ public SCMTrigger(String scmpoll_spec, boolean ignorePostCommitHooks) throws ANT * This trigger wants to ignore post-commit hooks. *

    * SCM plugins must respect this and not run this trigger for post-commit notifications. - * + * * @since 1.493 */ public boolean isIgnorePostCommitHooks() { @@ -167,7 +167,7 @@ public void run() { /** * Run the SCM trigger with additional build actions. Used by SubversionRepositoryStatus * to trigger a build at a specific revision number. - * + * * @since 1.375 */ public void run(Action[] additionalActions) { @@ -179,14 +179,14 @@ public void run(Action[] additionalActions) { LOGGER.fine("Scheduling a polling for "+job); if (d.synchronousPolling) { - LOGGER.fine("Running the trigger directly without threading, " + - "as it's already taken care of by Trigger.Cron"); + LOGGER.fine("Running the trigger directly without threading, " + + "as it's already taken care of by Trigger.Cron"); new Runner(additionalActions).run(); } else { // schedule the polling. // even if we end up submitting this too many times, that's OK. // the real exclusion control happens inside Runner. - LOGGER.fine("scheduling the trigger to (asynchronously) run"); + LOGGER.fine("scheduling the trigger to (asynchronously) run"); d.queue.execute(new Runner(additionalActions)); d.clogCheck(); } @@ -426,7 +426,7 @@ public BuildAction(Run run) { this.run = run; build = run instanceof AbstractBuild ? (AbstractBuild) run : null; } - + @Deprecated public BuildAction(AbstractBuild build) { this((Run) build); @@ -476,7 +476,7 @@ public void doPollingLog(StaplerRequest req, StaplerResponse rsp) throws IOExcep public AnnotatedLargeText getPollingLogText() { return new AnnotatedLargeText<>(getPollingLogFile(), Charset.defaultCharset(), true, this); } - + /** * Used from {@code polling.jelly} to write annotated polling log to the given output. */ @@ -562,12 +562,9 @@ public class Runner implements Runnable { public Runner() { this(null); } - - @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH", justification = "False positive") + public Runner(Action[] actions) { - if (job == null) { - throw new NullPointerException("Runner can't be instantiated when job is null"); - } + Objects.requireNonNull(job, "Runner can't be instantiated when job is null"); if (actions == null) { additionalActions = new Action[0]; @@ -575,7 +572,7 @@ public Runner(Action[] actions) { additionalActions = Arrays.copyOf(actions, actions.length); } } - + /** * Where the log file is written. */ diff --git a/core/src/main/java/hudson/triggers/TimerTrigger.java b/core/src/main/java/hudson/triggers/TimerTrigger.java index 290cf9534cd7..79cfb78d323b 100644 --- a/core/src/main/java/hudson/triggers/TimerTrigger.java +++ b/core/src/main/java/hudson/triggers/TimerTrigger.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Jean-Baptiste Quenot, Martin Eigenbrodt * 2015 Kanstantsin Shautsou - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -82,7 +82,7 @@ public String getDisplayName() { public FormValidation doCheck(@QueryParameter String value, @AncestorInPath Item item) { return doCheckSpec(value, item); } - + /** * Performs syntax check. */ @@ -120,7 +120,7 @@ private void updateValidationsForNextRun(Collection validations, } } } - + public static class TimerTriggerCause extends Cause { @Override public String getShortDescription() { diff --git a/core/src/main/java/hudson/triggers/Trigger.java b/core/src/main/java/hudson/triggers/Trigger.java index 5126c8925da4..a308e004559a 100644 --- a/core/src/main/java/hudson/triggers/Trigger.java +++ b/core/src/main/java/hudson/triggers/Trigger.java @@ -258,12 +258,15 @@ public static void checkTriggers(final Calendar cal) { // terminated. // FIXME allow to set a global crontab spec previousSynchronousPolling = scmd.getExecutor().submit(new DependencyRunner(new ProjectRunnable() { - @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH", justification = "TODO needs triage") @Override public void run(AbstractProject p) { for (Trigger t : (Collection) p.getTriggers().values()) { if (t instanceof SCMTrigger) { - LOGGER.fine("synchronously triggering SCMTrigger for project " + t.job.getName()); + if (t.job != null) { + LOGGER.fine("synchronously triggering SCMTrigger for project " + t.job.getName()); + } else { + LOGGER.fine("synchronously triggering SCMTrigger for unknown project"); + } t.run(); } } diff --git a/core/src/main/java/hudson/util/ComboBoxModel.java b/core/src/main/java/hudson/util/ComboBoxModel.java index 210ee09f0200..af1a81cb5fcd 100644 --- a/core/src/main/java/hudson/util/ComboBoxModel.java +++ b/core/src/main/java/hudson/util/ComboBoxModel.java @@ -38,7 +38,7 @@ /** * Model object for dynamically filed combo box, which is really just {@code ArrayList} - * + * * @author Kohsuke Kawaguchi */ public class ComboBoxModel extends ArrayList implements HttpResponse { diff --git a/core/src/main/java/hudson/util/CompressedFile.java b/core/src/main/java/hudson/util/CompressedFile.java index 648972716144..1b4dac135e61 100644 --- a/core/src/main/java/hudson/util/CompressedFile.java +++ b/core/src/main/java/hudson/util/CompressedFile.java @@ -25,7 +25,6 @@ import com.jcraft.jzlib.GZIPInputStream; import com.jcraft.jzlib.GZIPOutputStream; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Util; import java.io.File; import java.io.FileNotFoundException; @@ -36,6 +35,7 @@ import java.io.Reader; import java.nio.charset.Charset; import java.nio.file.Files; +import java.nio.file.InvalidPathException; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; @@ -137,20 +137,32 @@ public String loadAsString() throws IOException { */ public void compress() { compressionThread.submit(new Runnable() { - @SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED_BAD_PRACTICE", justification = "TODO needs triage") @Override public void run() { - try { - try (InputStream in = read(); - OutputStream os = Files.newOutputStream(gz.toPath()); - OutputStream out = new GZIPOutputStream(os)) { - org.apache.commons.io.IOUtils.copy(in, out); - } + boolean success; + try (InputStream in = read(); + OutputStream os = Files.newOutputStream(gz.toPath()); + OutputStream out = new GZIPOutputStream(os)) { + org.apache.commons.io.IOUtils.copy(in, out); + out.flush(); + success = true; + } catch (IOException | InvalidPathException e) { + LOGGER.log(Level.WARNING, "Failed to compress " + file, e); + success = false; + } + + File fileToDelete; + if (success) { // if the compressed file is created successfully, remove the original - file.delete(); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to compress "+file,e); - gz.delete(); // in case a processing is left in the middle + fileToDelete = file; + } else { + // in case a processing is left in the middle + fileToDelete = gz; + } + try { + Files.deleteIfExists(fileToDelete.toPath()); + } catch (IOException | InvalidPathException e) { + LOGGER.log(Level.WARNING, "Failed to delete " + fileToDelete, e); } } }); diff --git a/core/src/main/java/hudson/util/DirScanner.java b/core/src/main/java/hudson/util/DirScanner.java index b31d9ad5dfd1..e78c63f41d3c 100644 --- a/core/src/main/java/hudson/util/DirScanner.java +++ b/core/src/main/java/hudson/util/DirScanner.java @@ -150,7 +150,7 @@ public void scan(File dir, FileVisitor visitor) throws IOException { private static final long serialVersionUID = 1L; } - + private static class DescendantFileSelector implements FileSelector{ private final Set alreadyDeselected; private final FilePath baseDirFP; @@ -161,7 +161,7 @@ private DescendantFileSelector(File basedir){ this.baseDirPathLength = basedir.getPath().length(); this.alreadyDeselected = new HashSet<>(); } - + @Override public boolean isSelected(File basedir, String filename, File file) throws BuildException { String parentName = file.getParent(); diff --git a/core/src/main/java/hudson/util/DoubleLaunchChecker.java b/core/src/main/java/hudson/util/DoubleLaunchChecker.java index 44a76b264cb7..b6c6400a5859 100644 --- a/core/src/main/java/hudson/util/DoubleLaunchChecker.java +++ b/core/src/main/java/hudson/util/DoubleLaunchChecker.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -87,7 +87,7 @@ public class DoubleLaunchChecker { public final File home; /** - * ID string of the other Hudson that we are colliding with. + * ID string of the other Hudson that we are colliding with. * Can be null. */ private String collidingId; diff --git a/core/src/main/java/hudson/util/ErrorObject.java b/core/src/main/java/hudson/util/ErrorObject.java index 26fb2f2f27ef..da9f6b292bbf 100644 --- a/core/src/main/java/hudson/util/ErrorObject.java +++ b/core/src/main/java/hudson/util/ErrorObject.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/hudson/util/FormFieldValidator.java b/core/src/main/java/hudson/util/FormFieldValidator.java index 466b65b3e891..8fb9bb219c5a 100644 --- a/core/src/main/java/hudson/util/FormFieldValidator.java +++ b/core/src/main/java/hudson/util/FormFieldValidator.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Jene Jasper, Tom Huybrechts - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -361,7 +361,7 @@ private HttpURLConnection openConnection(URL url) throws IOException { * Checks the file mask (specified in the 'value' query parameter) against * the current workspace. * @since 1.90. - * @deprecated as of 1.294. Use {@link FilePath#validateFileMask(String, boolean, boolean)} + * @deprecated as of 1.294. Use {@link FilePath#validateFileMask(String, boolean, boolean)} */ @Deprecated public static class WorkspaceFileMask extends FormFieldValidator { @@ -622,7 +622,7 @@ protected void check() throws IOException, ServletException { fail(); return; } - + java.util.Base64.getDecoder().decode(v); ok(); } catch (IOException | IllegalArgumentException e) { diff --git a/core/src/main/java/hudson/util/Function1.java b/core/src/main/java/hudson/util/Function1.java index aa7535d5903f..78fe9d085110 100644 --- a/core/src/main/java/hudson/util/Function1.java +++ b/core/src/main/java/hudson/util/Function1.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,7 +25,7 @@ /** * Unary function {@code y=f(x)}. - * + * * @author Kohsuke Kawaguchi */ public interface Function1 { diff --git a/core/src/main/java/hudson/util/HudsonIsLoading.java b/core/src/main/java/hudson/util/HudsonIsLoading.java index 49d04dc30152..14980e82835f 100644 --- a/core/src/main/java/hudson/util/HudsonIsLoading.java +++ b/core/src/main/java/hudson/util/HudsonIsLoading.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -36,7 +36,7 @@ * * Set this object to {@link ServletContext#setAttribute(String, Object)} "app" while * the loading activity is taking place. - * + * * @author Kohsuke Kawaguchi */ public class HudsonIsLoading { diff --git a/core/src/main/java/hudson/util/HudsonIsRestarting.java b/core/src/main/java/hudson/util/HudsonIsRestarting.java index 984022c67657..cf3ce0cbdad3 100644 --- a/core/src/main/java/hudson/util/HudsonIsRestarting.java +++ b/core/src/main/java/hudson/util/HudsonIsRestarting.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/hudson/util/OneShotEvent.java b/core/src/main/java/hudson/util/OneShotEvent.java index 19e119b5dfe2..ceec02dc2b48 100644 --- a/core/src/main/java/hudson/util/OneShotEvent.java +++ b/core/src/main/java/hudson/util/OneShotEvent.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -33,7 +33,7 @@ * *

    * Once the event becomes signaled, or the pandora's box is opened, - * every thread gets through freely, and there's no way to turn it back off. + * every thread gets through freely, and there's no way to turn it back off. * * @author Kohsuke Kawaguchi */ diff --git a/core/src/main/java/hudson/util/ProcessTree.java b/core/src/main/java/hudson/util/ProcessTree.java index 3be9c62d57ee..37f10c8cd2c1 100644 --- a/core/src/main/java/hudson/util/ProcessTree.java +++ b/core/src/main/java/hudson/util/ProcessTree.java @@ -109,7 +109,7 @@ public abstract class ProcessTree implements Iterable, IProcessTree, * Lazily obtained {@link ProcessKiller}s to be applied on this process tree. */ private transient volatile List killers; - + /** * Flag to skip the veto check since there aren't any. */ @@ -119,7 +119,7 @@ public abstract class ProcessTree implements Iterable, IProcessTree, private ProcessTree() { skipVetoes = false; } - + private ProcessTree(boolean vetoesExist) { skipVetoes = !vetoesExist; } @@ -288,12 +288,12 @@ void killByKiller() throws InterruptedException { public abstract void killRecursively() throws InterruptedException; /** - * @return The first non-null {@link VetoCause} provided by a process killing veto extension for this OSProcess. + * @return The first non-null {@link VetoCause} provided by a process killing veto extension for this OSProcess. * null if no one objects killing the process. */ protected @CheckForNull VetoCause getVeto() { String causeMessage = null; - + // Quick check, does anything exist to check against if (!skipVetoes) { try { @@ -308,7 +308,7 @@ void killByKiller() throws InterruptedException { LOGGER.log(Level.WARNING, "Interrupted Exception while checking for vetoes", e); } } - + if (causeMessage != null) { return new VetoCause(causeMessage); } @@ -368,14 +368,14 @@ public T act(ProcessCallable callable) throws IOException, InterruptedExc Object writeReplace() { return new SerializedProcess(pid); } - + private class CheckVetoes extends SlaveToMasterCallable { private IOSProcess process; - + CheckVetoes(IOSProcess processToCheck) { process = processToCheck; } - + @Override public String call() throws IOException { for (ProcessKillingVeto vetoExtension : ProcessKillingVeto.all()) { @@ -429,7 +429,7 @@ public interface ProcessCallable extends Serializable { /* package */ static volatile Boolean vetoersExist; - + /** * Gets the {@link ProcessTree} of the current system * that JVM runs in, or in the worst case return the default one @@ -458,10 +458,10 @@ public static ProcessTree get() { LOGGER.log(Level.WARNING, "Error while determining if vetoers exist", e); } } - + // Null-check in case the previous call worked boolean vetoes = vetoersExist == null ? true : vetoersExist; - + try { if(File.pathSeparatorChar==';') return new Windows(vetoes); @@ -484,7 +484,7 @@ public static ProcessTree get() { return DEFAULT; } - + private static class DoVetoersExist extends SlaveToMasterCallable { @Override public Boolean call() throws IOException { @@ -519,7 +519,7 @@ public void killRecursively() { @Override public void kill() throws InterruptedException { - if (getVeto() != null) + if (getVeto() != null) return; proc.destroy(); killByKiller(); @@ -546,11 +546,11 @@ public void killAll(@NonNull Map modelEnvVars) { }; private class WindowsOSProcess extends OSProcess { - + private final WinProcess p; private EnvVars env; private List args; - + WindowsOSProcess(WinProcess p) { super(p.getPid()); this.p = p; @@ -565,7 +565,7 @@ public OSProcess getParent() { @Override public void killRecursively() throws InterruptedException { - if (getVeto() != null) + if (getVeto() != null) return; LOGGER.log(FINER, "Killing recursively {0}", getPid()); @@ -580,7 +580,7 @@ public void kill() throws InterruptedException { if (getVeto() != null) { return; } - + LOGGER.log(FINER, "Killing {0}", getPid()); // Firstly try to kill it gracefully, then do a forcekill if it does not help (algorithm is described in JENKINS-17116) killSoftly(); @@ -636,7 +636,7 @@ public synchronized EnvVars getEnvironmentVariables() { } return env; } - + private synchronized EnvVars getEnvironmentVariables2() throws WindowsOSProcessException { if(env !=null) { return env; @@ -650,7 +650,7 @@ private synchronized EnvVars getEnvironmentVariables2() throws WindowsOSProcessE } return env; } - + private boolean hasMatchingEnvVars2(Map modelEnvVar) throws WindowsOSProcessException { if(modelEnvVar.isEmpty()) // sanity check so that we don't start rampage. @@ -666,8 +666,8 @@ private boolean hasMatchingEnvVars2(Map modelEnvVar) throws Windo return true; } } - - //TODO: Cleanup once Winp provides proper API + + //TODO: Cleanup once Winp provides proper API /** * Wrapper for runtime {@link WinpException}. */ @@ -675,7 +675,7 @@ private static class WindowsOSProcessException extends Exception { WindowsOSProcessException(WinpException ex) { super(ex); } - + WindowsOSProcessException(String message, WinpException ex) { super(message, ex); } @@ -684,7 +684,7 @@ private static class WindowsOSProcessException extends Exception { private static final class Windows extends Local { Windows(boolean vetoesExist) { super(vetoesExist); - + for (final WinProcess p : WinProcess.all()) { int pid = p.getPid(); if(pid == 0 || pid == 4) continue; // skip the System Idle and System processes @@ -729,7 +729,7 @@ public void killAll(@NonNull Map modelEnvVars) throws Interrupte static { WinProcess.enableDebugPrivilege(); } - + private static boolean hasMatchingEnvVars(@NonNull OSProcess p, @NonNull Map modelEnvVars) throws WindowsOSProcessException { if (p instanceof WindowsOSProcess) { @@ -770,7 +770,7 @@ public void killAll(@NonNull Map modelEnvVars) throws Interrupte abstract static class ProcfsUnix extends Unix { ProcfsUnix(boolean vetoersExist) { super(vetoersExist); - + File[] processes = new File("/proc").listFiles(File::isDirectory); if(processes==null) { LOGGER.info("No /proc"); @@ -819,7 +819,7 @@ public void kill() throws InterruptedException { } private void kill(long deadline) throws InterruptedException { - if (getVeto() != null) + if (getVeto() != null) return; try { int pid = getPid(); @@ -972,7 +972,7 @@ static class Linux extends ProcfsUnix { Linux(boolean vetoersExist) { super(vetoersExist); } - + @Override protected LinuxProcess createProcess(int pid) throws IOException { return new LinuxProcess(pid); @@ -1086,7 +1086,7 @@ static class AIX extends ProcfsUnix { AIX(boolean vetoersExist) { super(vetoersExist); } - + @Override protected OSProcess createProcess(final int pid) throws IOException { return new AIXProcess(pid); @@ -1121,44 +1121,44 @@ private AIXProcess(int pid) throws IOException { super(pid); try (RandomAccessFile pstatus = new RandomAccessFile(getFile("status"), "r")) { - // typedef struct pstatus { - // uint32_t pr_flag; /* process flags from proc struct p_flag */ - // uint32_t pr_flag2; /* process flags from proc struct p_flag2 */ - // uint32_t pr_flags; /* /proc flags */ - // uint32_t pr_nlwp; /* number of threads in the process */ - // char pr_stat; /* process state from proc p_stat */ - // char pr_dmodel; /* data model for the process */ - // char pr__pad1[6]; /* reserved for future use */ - // pr_sigset_t pr_sigpend; /* set of process pending signals */ - // prptr64_t pr_brkbase; /* address of the process heap */ - // uint64_t pr_brksize; /* size of the process heap, in bytes */ - // prptr64_t pr_stkbase; /* address of the process stack */ - // uint64_t pr_stksize; /* size of the process stack, in bytes */ - // uint64_t pr_pid; /* process id */ - // uint64_t pr_ppid; /* parent process id */ - // uint64_t pr_pgid; /* process group id */ - // uint64_t pr_sid; /* session id */ - // pr_timestruc64_t pr_utime; /* process user cpu time */ - // pr_timestruc64_t pr_stime; /* process system cpu time */ - // pr_timestruc64_t pr_cutime; /* sum of children's user times */ - // pr_timestruc64_t pr_cstime; /* sum of children's system times */ - // pr_sigset_t pr_sigtrace; /* mask of traced signals */ - // fltset_t pr_flttrace; /* mask of traced hardware faults */ - // uint32_t pr_sysentry_offset; /* offset into pstatus file of sysset_t - // * identifying system calls traced on - // * entry. If 0, then no entry syscalls - // * are being traced. */ - // uint32_t pr_sysexit_offset; /* offset into pstatus file of sysset_t - // * identifying system calls traced on - // * exit. If 0, then no exit syscalls - // * are being traced. */ - // uint64_t pr__pad[8]; /* reserved for future use */ - // lwpstatus_t pr_lwp; /* "representative" thread status */ - // } pstatus_t; + // typedef struct pstatus { + // uint32_t pr_flag; /* process flags from proc struct p_flag */ + // uint32_t pr_flag2; /* process flags from proc struct p_flag2 */ + // uint32_t pr_flags; /* /proc flags */ + // uint32_t pr_nlwp; /* number of threads in the process */ + // char pr_stat; /* process state from proc p_stat */ + // char pr_dmodel; /* data model for the process */ + // char pr__pad1[6]; /* reserved for future use */ + // pr_sigset_t pr_sigpend; /* set of process pending signals */ + // prptr64_t pr_brkbase; /* address of the process heap */ + // uint64_t pr_brksize; /* size of the process heap, in bytes */ + // prptr64_t pr_stkbase; /* address of the process stack */ + // uint64_t pr_stksize; /* size of the process stack, in bytes */ + // uint64_t pr_pid; /* process id */ + // uint64_t pr_ppid; /* parent process id */ + // uint64_t pr_pgid; /* process group id */ + // uint64_t pr_sid; /* session id */ + // pr_timestruc64_t pr_utime; /* process user cpu time */ + // pr_timestruc64_t pr_stime; /* process system cpu time */ + // pr_timestruc64_t pr_cutime; /* sum of children's user times */ + // pr_timestruc64_t pr_cstime; /* sum of children's system times */ + // pr_sigset_t pr_sigtrace; /* mask of traced signals */ + // fltset_t pr_flttrace; /* mask of traced hardware faults */ + // uint32_t pr_sysentry_offset; /* offset into pstatus file of sysset_t + // * identifying system calls traced on + // * entry. If 0, then no entry syscalls + // * are being traced. */ + // uint32_t pr_sysexit_offset; /* offset into pstatus file of sysset_t + // * identifying system calls traced on + // * exit. If 0, then no exit syscalls + // * are being traced. */ + // uint64_t pr__pad[8]; /* reserved for future use */ + // lwpstatus_t pr_lwp; /* "representative" thread status */ + // } pstatus_t; pstatus.seek(17); // offset of pr_dmodel - byte pr_dmodel = pstatus.readByte(); + byte pr_dmodel = pstatus.readByte(); if (pr_dmodel == PR_MODEL_ILP32) { b64 = false; @@ -1173,7 +1173,7 @@ private AIXProcess(int pid) throws IOException { if (adjust((int)pstatus.readLong()) != pid) throw new IOException("pstatus PID mismatch"); // sanity check - ppid = adjust((int)pstatus.readLong()); // AIX pids are stored as a 64 bit integer, + ppid = adjust((int)pstatus.readLong()); // AIX pids are stored as a 64 bit integer, // but the first 4 bytes are always 0 } @@ -1269,7 +1269,7 @@ public synchronized List getArguments() { arguments.add(readLine(fd, addr, "arg["+ n +"]")); } } finally { - LIBC.close(fd); + LIBC.close(fd); } } catch (IOException | LastErrorException e) { // failed to read. this can happen under normal circumstances (most notably permission denied) @@ -1317,7 +1317,7 @@ public synchronized EnvVars getEnvironmentVariables() { envVars.addLine(readLine(fd, addr, "env["+ n +"]")); } } finally { - LIBC.close(fd); + LIBC.close(fd); } } catch (IOException | LastErrorException e) { // failed to read. this can happen under normal circumstances (most notably permission denied) @@ -1417,7 +1417,7 @@ static class Solaris extends ProcfsUnix { Solaris(boolean vetoersExist) { super(vetoersExist); } - + @Override protected OSProcess createProcess(final int pid) throws IOException { return new SolarisProcess(pid); @@ -1535,9 +1535,9 @@ public synchronized List getArguments() { return arguments; arguments = new ArrayList<>(argc); - if (argc == 0) { - return arguments; - } + if (argc == 0) { + return arguments; + } int psize = b64 ? 8 : 4; Memory m = new Memory(psize); @@ -1572,9 +1572,9 @@ public synchronized EnvVars getEnvironmentVariables() { return envVars; envVars = new EnvVars(); - if (envp == 0) { - return envVars; - } + if (envp == 0) { + return envVars; + } int psize = b64 ? 8 : 4; Memory m = new Memory(psize); @@ -2133,7 +2133,7 @@ public abstract static class Local extends ProcessTree { @Deprecated Local() { } - + Local(boolean vetoesExist) { super(vetoesExist); } @@ -2151,10 +2151,10 @@ public Remote(ProcessTree proxy, Channel ch) { for (Map.Entry e : proxy.processes.entrySet()) processes.put(e.getKey(),new RemoteProcess(e.getValue(),ch)); } - + public Remote(ProcessTree proxy, Channel ch, boolean vetoersExist) { super(vetoersExist); - + this.proxy = ch.export(IProcessTree.class,proxy); for (Map.Entry e : proxy.processes.entrySet()) processes.put(e.getKey(),new RemoteProcess(e.getValue(),ch)); diff --git a/core/src/main/java/hudson/util/RobustReflectionConverter.java b/core/src/main/java/hudson/util/RobustReflectionConverter.java index 96b10f6ef9e4..368a5e4ffa74 100644 --- a/core/src/main/java/hudson/util/RobustReflectionConverter.java +++ b/core/src/main/java/hudson/util/RobustReflectionConverter.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -122,7 +122,7 @@ void addCriticalField(Class clazz, String field) { criticalFieldsLock.writeLock().unlock(); } } - + private boolean hasCriticalField(Class clazz, String field) { // Lock the write lock criticalFieldsLock.readLock().lock(); @@ -383,7 +383,7 @@ public Object doUnmarshal(final Object result, final HierarchicalStreamReader re // Report any class/field errors in Saveable objects if it happens during loading of existing data from disk if (shouldReportUnloadableDataForCurrentUser() && context.get("ReadError") != null && context.get("Saveable") == result) { // Avoid any error in OldDataMonitor to be catastrophic. See JENKINS-62231 and JENKINS-59582 - // The root cause is the OldDataMonitor extension is not ready before a plugin triggers an error, for + // The root cause is the OldDataMonitor extension is not ready before a plugin triggers an error, for // example when trying to load a field that was created by a new version and you downgrade to the previous // one. try { diff --git a/core/src/main/java/hudson/util/Secret.java b/core/src/main/java/hudson/util/Secret.java index 6da075b331a5..d352b43803b0 100644 --- a/core/src/main/java/hudson/util/Secret.java +++ b/core/src/main/java/hudson/util/Secret.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi * Copyright (c) 2016, CloudBees Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -122,7 +122,7 @@ public int hashCode() { /** * Encrypts {@link #value} and returns it in an encoded printable form. * - * @see #toString() + * @see #toString() */ public String getEncryptedValue() { try { diff --git a/core/src/main/java/hudson/util/Service.java b/core/src/main/java/hudson/util/Service.java index 7b33d8b55b1b..6ea3f7955c1c 100644 --- a/core/src/main/java/hudson/util/Service.java +++ b/core/src/main/java/hudson/util/Service.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/hudson/util/WriterOutputStream.java b/core/src/main/java/hudson/util/WriterOutputStream.java deleted file mode 100644 index e86986109756..000000000000 --- a/core/src/main/java/hudson/util/WriterOutputStream.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package hudson.util; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.Writer; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CoderResult; -import java.nio.charset.CodingErrorAction; -import java.nio.charset.StandardCharsets; -import java.nio.charset.UnsupportedCharsetException; - -/** - * {@link OutputStream} that writes to {@link Writer} - * by assuming the platform default encoding. - * - * @author Kohsuke Kawaguchi - * @deprecated since 2008-05-28. - * Use the one in stapler. - */ -@Deprecated -public class WriterOutputStream extends OutputStream { - private final Writer writer; - private final CharsetDecoder decoder; - - private java.nio.ByteBuffer buf = java.nio.ByteBuffer.allocate(1024); - private CharBuffer out = CharBuffer.allocate(1024); - - public WriterOutputStream(Writer out) { - this.writer = out; - decoder = DEFAULT_CHARSET.newDecoder(); - decoder.onMalformedInput(CodingErrorAction.REPLACE); - decoder.onUnmappableCharacter(CodingErrorAction.REPLACE); - } - - @Override - public void write(int b) throws IOException { - if(buf.remaining()==0) - decode(false); - buf.put((byte)b); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - while(len>0) { - if(buf.remaining()==0) - decode(false); - int sz = Math.min(buf.remaining(),len); - buf.put(b,off,sz); - off += sz; - len -= sz; - } - } - - @Override - public void flush() throws IOException { - decode(false); - flushOutput(); - writer.flush(); - } - - private void flushOutput() throws IOException { - writer.write(out.array(),0,out.position()); - out.clear(); - } - - @Override - public void close() throws IOException { - decode(true); - flushOutput(); - writer.close(); - - buf.rewind(); - } - - /** - * Decodes the contents of {@link #buf} as much as possible to {@link #out}. - * If necessary {@link #out} is further sent to {@link #writer}. - * - *

    - * When this method returns, the {@link #buf} is back to the 'accumulation' - * mode. - * - * @param last - * if true, tell the decoder that all the input bytes are ready. - */ - private void decode(boolean last) throws IOException { - buf.flip(); - while(true) { - CoderResult r = decoder.decode(buf, out, last); - if(r==CoderResult.OVERFLOW) { - flushOutput(); - continue; - } - if(r==CoderResult.UNDERFLOW) { - buf.compact(); - return; - } - // otherwise treat it as an error - r.throwException(); - } - } - - private static final Charset DEFAULT_CHARSET = getDefaultCharset(); - - private static Charset getDefaultCharset() { - try { - String encoding = System.getProperty("file.encoding"); - return Charset.forName(encoding); - } catch (UnsupportedCharsetException e) { - return StandardCharsets.UTF_8; - } - } -} diff --git a/core/src/main/java/hudson/util/jna/package-info.java b/core/src/main/java/hudson/util/jna/package-info.java index 637a0c66ffdd..a2abf2e79aa3 100644 --- a/core/src/main/java/hudson/util/jna/package-info.java +++ b/core/src/main/java/hudson/util/jna/package-info.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/jenkins/PluginSubtypeMarker.java b/core/src/main/java/jenkins/PluginSubtypeMarker.java index 162347ddda12..3a115ed37389 100644 --- a/core/src/main/java/jenkins/PluginSubtypeMarker.java +++ b/core/src/main/java/jenkins/PluginSubtypeMarker.java @@ -54,7 +54,6 @@ */ @SupportedAnnotationTypes("*") @MetaInfServices(Processor.class) -@SuppressWarnings("Since15") public class PluginSubtypeMarker extends AbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { diff --git a/core/src/main/java/jenkins/fingerprints/FingerprintStorage.java b/core/src/main/java/jenkins/fingerprints/FingerprintStorage.java index 39323ec38a16..e1692aae7a37 100644 --- a/core/src/main/java/jenkins/fingerprints/FingerprintStorage.java +++ b/core/src/main/java/jenkins/fingerprints/FingerprintStorage.java @@ -55,7 +55,7 @@ public static FingerprintStorage get() { /** * Returns the file system based {@link FileFingerprintStorage} configured on the system. - * @deprecated since TODO, use {@code ExtensionList.lookupSingleton(FileFingerprintStorage.class)} instead. + * @deprecated since 2.324, use {@code ExtensionList.lookupSingleton(FileFingerprintStorage.class)} instead. */ @Deprecated public static FingerprintStorage getFileFingerprintStorage() { diff --git a/core/src/main/java/jenkins/install/InstallUtil.java b/core/src/main/java/jenkins/install/InstallUtil.java index bf126df40a27..3cd4079e9341 100644 --- a/core/src/main/java/jenkins/install/InstallUtil.java +++ b/core/src/main/java/jenkins/install/InstallUtil.java @@ -85,7 +85,7 @@ public T get() { return functions.next().apply(this); } } - + /** * Proceed to the state following the provided one */ @@ -95,7 +95,7 @@ public static void proceedToNextStateFrom(InstallState prior) { Jenkins.get().setInstallState(next); } } - + /** * Returns the next state during a transition from the current install state */ @@ -106,7 +106,7 @@ public static void proceedToNextStateFrom(InstallState prior) { } // Terminal condition: getNextState() on the current install state installStateFilterChain.add(input -> { - // Initially, install state is unknown and + // Initially, install state is unknown and // needs to be determined if (current == null || InstallState.UNKNOWN.equals(current)) { return getDefaultInstallState(); @@ -124,11 +124,11 @@ public static void proceedToNextStateFrom(InstallState prior) { } return states.get(current); }); - + ProviderChain chain = new ProviderChain<>(installStateFilterChain.iterator()); return chain.get(); } - + private static InstallState getDefaultInstallState() { // Support a simple state override. Useful for testing. String stateOverride = System.getProperty("jenkins.install.state", System.getenv("jenkins.install.state")); @@ -139,18 +139,18 @@ private static InstallState getDefaultInstallState() { throw new IllegalStateException("Unknown install state override specified on the commandline: '" + stateOverride + "'.", e); } } - + // Support a 3-state flag for running or disabling the setup wizard String shouldRunFlag = SystemProperties.getString("jenkins.install.runSetupWizard"); boolean shouldRun = "true".equalsIgnoreCase(shouldRunFlag); boolean shouldNotRun = "false".equalsIgnoreCase(shouldRunFlag); - + // install wizard will always run if environment specified if (!shouldRun) { if (Functions.getIsUnitTest()) { return InstallState.TEST; } - + if (SystemProperties.getBoolean("hudson.Main.development")) { return InstallState.DEVELOPMENT; } @@ -161,7 +161,7 @@ private static InstallState getDefaultInstallState() { // has the setup wizard been completed? if (!SetupWizard.getUpdateStateFile().exists()) { Jenkins j = Jenkins.get(); - + // Allow for skipping if(shouldNotRun) { InstallState.INITIAL_SETUP_COMPLETED.initializeState(); @@ -280,10 +280,10 @@ private static String getCurrentExecVersion() { * Returns a list of any plugins that are persisted in the installing list */ @SuppressWarnings("unchecked") - public static synchronized @CheckForNull Map getPersistedInstallStatus() { + public static synchronized @CheckForNull Map getPersistedInstallStatus() { File installingPluginsFile = getInstallingPluginsFile(); if(installingPluginsFile == null || !installingPluginsFile.exists()) { - return null; + return null; } return (Map)new XStream().fromXML(installingPluginsFile); } @@ -293,29 +293,29 @@ private static String getCurrentExecVersion() { */ public static synchronized void persistInstallStatus(List installingPlugins) { File installingPluginsFile = getInstallingPluginsFile(); - if(installingPlugins == null || installingPlugins.isEmpty()) { - try { - Files.deleteIfExists(installingPluginsFile.toPath()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - return; - } - LOGGER.fine("Writing install state to: " + installingPluginsFile.getAbsolutePath()); - Map statuses = new HashMap<>(); - for(UpdateCenterJob j : installingPlugins) { - if(j instanceof InstallationJob && j.getCorrelationId() != null) { // only include install jobs with a correlation id (directly selected) - InstallationJob ij = (InstallationJob)j; - InstallationStatus status = ij.status; - String statusText = status.getType(); - if(status instanceof Installing) { // flag currently installing plugins as pending - statusText = "Pending"; - } - statuses.put(ij.plugin.name, statusText); - } - } + if(installingPlugins == null || installingPlugins.isEmpty()) { + try { + Files.deleteIfExists(installingPluginsFile.toPath()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return; + } + LOGGER.fine("Writing install state to: " + installingPluginsFile.getAbsolutePath()); + Map statuses = new HashMap<>(); + for(UpdateCenterJob j : installingPlugins) { + if(j instanceof InstallationJob && j.getCorrelationId() != null) { // only include install jobs with a correlation id (directly selected) + InstallationJob ij = (InstallationJob)j; + InstallationStatus status = ij.status; + String statusText = status.getType(); + if(status instanceof Installing) { // flag currently installing plugins as pending + statusText = "Pending"; + } + statuses.put(ij.plugin.name, statusText); + } + } try { - String installingPluginXml = new XStream().toXML(statuses); + String installingPluginXml = new XStream().toXML(statuses); FileUtils.write(installingPluginsFile, installingPluginXml); } catch (IOException e) { LOGGER.log(SEVERE, "Failed to save " + installingPluginsFile.getAbsolutePath(), e); @@ -325,7 +325,7 @@ public static synchronized void persistInstallStatus(List insta /** * Call to remove any active install status */ - public static void clearInstallStatus() { - persistInstallStatus(null); - } + public static void clearInstallStatus() { + persistInstallStatus(null); + } } diff --git a/core/src/main/java/jenkins/install/SetupWizard.java b/core/src/main/java/jenkins/install/SetupWizard.java index feaa0c17e7e8..6e889cd772bb 100644 --- a/core/src/main/java/jenkins/install/SetupWizard.java +++ b/core/src/main/java/jenkins/install/SetupWizard.java @@ -78,7 +78,7 @@ /** * A Jenkins instance used during first-run to provide a limited set of services while * initial installation is in progress - * + * * @since 2.0 */ @Restricted(NoExternalUse.class) @@ -99,20 +99,20 @@ public SetupWizard() { private static final String ADMIN_INITIAL_API_TOKEN_PROPERTY_NAME = SetupWizard.class.getName() + ".adminInitialApiToken"; /** - * This property determines the behavior during the SetupWizard install phase concerning the API Token creation + * This property determines the behavior during the SetupWizard install phase concerning the API Token creation * for the initial admin account. * The behavior depends on the provided value: * - true - * A token is generated using random value at startup and the information is put + * A token is generated using random value at startup and the information is put * in the file "$JENKINS_HOME/secrets/initialAdminApiToken". - * - [2-char hash version][32-hex-char of secret], where the hash version is currently only 11. + * - [2-char hash version][32-hex-char of secret], where the hash version is currently only 11. * E.g. 110123456789abcdef0123456789abcdef. * A fixed API Token will be created for the user with that plain value as the token. * It is strongly recommended to use it to generate a new one (random) and then revoke it. * See {@link ApiTokenProperty#generateNewToken(String)} and {@link ApiTokenProperty#revokeAllTokensExceptOne(String)} - * for scripting methods or using the web API calls: - * /user/[user-login]/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken and - * /user/[user-login]/descriptorByName/jenkins.security.ApiTokenProperty/revokeAllExcept + * for scripting methods or using the web API calls: + * /user/[user-login]/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken and + * /user/[user-login]/descriptorByName/jenkins.security.ApiTokenProperty/revokeAllExcept * - @[file-location] where the file contains plain text value of the token, all stuff explained above is applicable * The application will not delete the file after read, so the script is responsible to clean up the stuff * @@ -139,7 +139,7 @@ public String getDisplayName() { */ /*package*/ void init(boolean newInstall) throws IOException, InterruptedException { Jenkins jenkins = Jenkins.get(); - + if(newInstall) { // Create an admin user by default with a difficult password FilePath iapf = getInitialAdminPasswordFile(); @@ -148,27 +148,27 @@ public String getDisplayName() { HudsonPrivateSecurityRealm securityRealm = new HudsonPrivateSecurityRealm(false, false, null); jenkins.setSecurityRealm(securityRealm); String randomUUID = UUID.randomUUID().toString().replace("-", "").toLowerCase(Locale.ENGLISH); - + // create an admin user User initialAdmin = securityRealm.createAccount(SetupWizard.initialSetupAdminUserName, randomUUID); - + if (ADMIN_INITIAL_API_TOKEN != null) { createInitialApiToken(initialAdmin); } - + // JENKINS-33599 - write to a file in the jenkins home directory // most native packages of Jenkins creates a machine user account 'jenkins' to run Jenkins, // and use group 'jenkins' for admins. So we allow groups to read this file iapf.touch(System.currentTimeMillis()); iapf.chmod(0640); iapf.write(randomUUID + System.lineSeparator(), "UTF-8"); - - + + // Lock Jenkins down: FullControlOnceLoggedInAuthorizationStrategy authStrategy = new FullControlOnceLoggedInAuthorizationStrategy(); authStrategy.setAllowAnonymousRead(false); jenkins.setAuthorizationStrategy(authStrategy); - + // Disable jnlp by default, but honor system properties jenkins.setSlaveAgentPort(SystemProperties.getInteger(Jenkins.class.getName()+".slaveAgentPort",-1)); @@ -179,7 +179,7 @@ public String getDisplayName() { bc.commit(); } } - + if(iapf.exists()) { String setupKey = iapf.readToString().trim(); String ls = System.lineSeparator(); @@ -276,7 +276,7 @@ private void tearDownFilter() { throw new RuntimeException("Unable to remove PluginServletFilter for the SetupWizard", e); } } - + /** * Indicates a generated password should be used - e.g. this is a new install, no security realm set up */ @@ -370,7 +370,7 @@ public HttpResponse doCreateAdminUser(StaplerRequest req, StaplerResponse rsp) t Authentication auth = new UsernamePasswordAuthenticationToken(newUser.getId(), req.getParameter("password1")); auth = securityRealm.getSecurityComponents().manager2.authenticate(auth); SecurityContextHolder.getContext().setAuthentication(auth); - + HttpSession session = req.getSession(false); if (session != null) { // avoid session fixation @@ -382,7 +382,7 @@ public HttpResponse doCreateAdminUser(StaplerRequest req, StaplerResponse rsp) t String sessionSeed = userSeed.getSeed(); // include the new seed newSession.setAttribute(UserSeedProperty.USER_SESSION_SEED, sessionSeed); - + CrumbIssuer crumbIssuer = Jenkins.get().getCrumbIssuer(); JSONObject data = new JSONObject(); if (crumbIssuer != null) { @@ -402,28 +402,28 @@ public HttpResponse doCreateAdminUser(StaplerRequest req, StaplerResponse rsp) t admin.save(); // recreate this initial user if something failed } } - } - + } + @POST @Restricted(NoExternalUse.class) public HttpResponse doConfigureInstance(StaplerRequest req, @QueryParameter String rootUrl) { Jenkins.get().checkPermission(Jenkins.ADMINISTER); - + Map errors = new HashMap<>(); // pre-check data checkRootUrl(errors, rootUrl); - + if(!errors.isEmpty()){ return HttpResponses.errorJSON(Messages.SetupWizard_ConfigureInstance_ValidationErrors(), errors); } - + // use the parameters to configure the instance useRootUrl(errors, rootUrl); - + if(!errors.isEmpty()){ return HttpResponses.errorJSON(Messages.SetupWizard_ConfigureInstance_ValidationErrors(), errors); } - + InstallUtil.proceedToNextStateFrom(InstallState.CONFIGURE_INSTANCE); CrumbIssuer crumbIssuer = Jenkins.get().getCrumbIssuer(); @@ -433,7 +433,7 @@ public HttpResponse doConfigureInstance(StaplerRequest req, @QueryParameter Stri } return HttpResponses.okJSON(data); } - + private void checkRootUrl(Map errors, @CheckForNull String rootUrl){ if(rootUrl == null){ errors.put("rootUrl", Messages.SetupWizard_ConfigureInstance_RootUrl_Empty()); @@ -443,7 +443,7 @@ private void checkRootUrl(Map errors, @CheckForNull String rootU errors.put("rootUrl", Messages.SetupWizard_ConfigureInstance_RootUrl_Invalid()); } } - + private void useRootUrl(Map errors, @CheckForNull String rootUrl){ LOGGER.log(Level.FINE, "Root URL set during SetupWizard to {0}", new Object[]{ rootUrl }); JenkinsLocationConfiguration.getOrDie().setUrl(rootUrl); @@ -452,7 +452,7 @@ private void useRootUrl(Map errors, @CheckForNull String rootUrl /*package*/ void setCurrentLevel(VersionNumber v) throws IOException { FileUtils.writeStringToFile(getUpdateStateFile(), v.toString(), StandardCharsets.UTF_8); } - + /** * File that captures the state of upgrade. * @@ -461,7 +461,7 @@ private void useRootUrl(Map errors, @CheckForNull String rootUrl /*package*/ static File getUpdateStateFile() { return new File(Jenkins.get().getRootDir(),"jenkins.install.UpgradeWizard.state"); } - + /** * What is the version the upgrade wizard has run the last time and upgraded to?. * If {@link #getUpdateStateFile()} is missing, presumes the baseline is 1.0 @@ -482,7 +482,7 @@ public VersionNumber getCurrentLevel() { } return from; } - + /** * Returns the initial plugin list in JSON format */ @@ -504,7 +504,7 @@ public HttpResponse doPlatformPluginList() throws IOException { } return HttpResponses.okJSON(); } - + /** * Returns whether the system needs a restart, and if it is supported * e.g. { restartRequired: true, restartSupported: false } @@ -531,7 +531,7 @@ public JSONArray getPlatformPluginUpdates() { } return getPlatformPluginsForUpdate(version, Jenkins.getVersion()); } - + /** * Gets the suggested plugin list from the update sites, falling back to a local version * @return JSON array with the categorized plugin list @@ -551,7 +551,7 @@ public JSONArray getPlatformPluginUpdates() { } try { URLConnection connection = ProxyConfiguration.open(new URL(suggestedPluginUrl)); - + try { String initialPluginJson = IOUtils.toString(connection.getInputStream(), StandardCharsets.UTF_8); @@ -624,7 +624,7 @@ public JSONArray getPlatformPluginUpdates() { if (category instanceof JSONObject) { JSONObject cat = (JSONObject)category; JSONArray plugins = cat.getJSONArray("plugins"); - + nextPlugin: for (Iterator pluginIterator = plugins.iterator(); pluginIterator.hasNext();) { Object pluginData = pluginIterator.next(); if (pluginData instanceof JSONObject) { @@ -658,10 +658,10 @@ public JSONArray getPlatformPluginUpdates() { } } } - + pluginIterator.remove(); } - + if (plugins.isEmpty()) { categoryIterator.remove(); } @@ -676,7 +676,7 @@ public JSONArray getPlatformPluginUpdates() { public FilePath getInitialAdminPasswordFile() { return Jenkins.get().getRootPath().child("secrets/initialAdminPassword"); } - + /** * Gets the file used to store the initial admin API Token, in case the system property * {@link #ADMIN_INITIAL_API_TOKEN} is set to "true" (and only in this case). @@ -694,21 +694,21 @@ public HttpResponse doCompleteInstall() throws IOException, ServletException { completeSetup(); return HttpResponses.okJSON(); } - + /*package*/ void completeSetup() throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); InstallUtil.saveLastExecVersion(); setCurrentLevel(Jenkins.getVersion()); InstallUtil.proceedToNextStateFrom(InstallState.INITIAL_SETUP_COMPLETED); } - + /** * Gets all the install states */ public List getInstallStates() { return InstallState.all(); } - + /** * Returns an installState by name */ diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index b6eccb039b37..b89ed1e16334 100644 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -370,9 +370,9 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve @Deprecated private InstallState installState; - + /** - * If we're in the process of an initial setup, + * If we're in the process of an initial setup, * this will be set */ private transient SetupWizard setupWizard; @@ -891,7 +891,6 @@ protected Jenkins(File root, ServletContext context) throws IOException, Interru * If non-null, use existing plugin manager. create a new one. */ @SuppressFBWarnings({ - "DMI_RANDOM_USED_ONLY_ONCE", // TODO needs triage "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", // Trigger.timer "DM_EXIT" // Exit is wanted here }) @@ -934,9 +933,8 @@ protected Jenkins(File root, ServletContext context, PluginManager pluginManager if(secretFile.exists()) { secretKey = secretFile.readTrim(); } else { - SecureRandom sr = new SecureRandom(); byte[] random = new byte[32]; - sr.nextBytes(random); + RANDOM.nextBytes(random); secretKey = Util.toHexString(random); secretFile.write(secretKey); @@ -1093,7 +1091,7 @@ public ProxyConfiguration getProxy() { /** * Set the proxy configuration. - * + * * @param proxy the proxy to set * @since 2.205 */ @@ -1116,7 +1114,7 @@ public InstallState getInstallState() { } /** - * Update the current install state. This will invoke state.initializeState() + * Update the current install state. This will invoke state.initializeState() * when the state has been transitioned. */ public void setInstallState(@NonNull InstallState newState) { @@ -1658,11 +1656,11 @@ Descriptor findDescriptor(String shortClassName, Collection d : Functions.getSortedDescriptorsForGlobalConfigUnclassified()) result &= configureDescriptor(req,json,d); - + save(); updateComputerList(); if(result) @@ -4201,7 +4199,7 @@ public static void checkGoodName(String name) throws Failure { throw new Failure(Messages.Hudson_TrailingDot()); } } - + // looks good } @@ -4940,7 +4938,7 @@ public Map> getCategorizedManageme } return byCategory; } - + /** * If set, a currently active setup wizard - e.g. installation * @@ -4950,7 +4948,7 @@ public Map> getCategorizedManageme public SetupWizard getSetupWizard() { return setupWizard; } - + /** * Exposes the current user to {@code /me} URL. */ @@ -4986,7 +4984,7 @@ public Object getTarget() { } return this; } - + /** * Test a path to see if it is subject to mandatory read permission checks by container-managed security * @param restOfPath the URI, excluding the Jenkins root URI and query string @@ -5307,7 +5305,7 @@ private static void computeVersion(ServletContext context) { LOGGER.log(WARNING, e, () -> "Unable to read Jenkins version: " + e.getMessage()); } } - + VERSION = ver; context.setAttribute("version",ver); @@ -5463,9 +5461,9 @@ public boolean shouldShowStackTrace() { * Name of the system property escape hatch for SECURITY-2424. It allows to have back the legacy (and vulnerable) * behavior allowing a "good name" to end with a dot. This could be used to exploit two names colliding in the file * system to extract information. The files ending with a dot are only a problem on Windows. - * + * * The default value is true. - * + * * For detailed documentation: https://docs.microsoft.com/en-us/troubleshoot/windows-client/shell-experience/file-folder-name-whitespace-characters * @see #checkGoodName(String) */ @@ -5505,10 +5503,11 @@ public boolean shouldShowStackTrace() { /** * Automatically try to launch an agent when Jenkins is initialized or a new agent computer is created. */ - @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "TODO needs triage") - public static boolean AUTOMATIC_SLAVE_LAUNCH = true; + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static boolean AUTOMATIC_AGENT_LAUNCH = SystemProperties.getBoolean(Jenkins.class.getName() + ".automaticAgentLaunch", true); private static final Logger LOGGER = Logger.getLogger(Jenkins.class.getName()); + private static final SecureRandom RANDOM = new SecureRandom(); public static final PermissionGroup PERMISSIONS = Permission.HUDSON_PERMISSIONS; public static final Permission ADMINISTER = Permission.HUDSON_ADMINISTER; diff --git a/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java b/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java index 89d2b6e60cf0..b9ca47c2d2d0 100644 --- a/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java +++ b/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java @@ -48,7 +48,7 @@ public class JenkinsLocationConfiguration extends GlobalConfiguration implements @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "Accessible via System Groovy Scripts") public static /* not final */ boolean DISABLE_URL_VALIDATION = SystemProperties.getBoolean(JenkinsLocationConfiguration.class.getName() + ".disableUrlValidation"); - + @Restricted(NoExternalUse.class) public static final int ORDINAL = 200; @@ -66,7 +66,7 @@ public class JenkinsLocationConfiguration extends GlobalConfiguration implements public static @NonNull JenkinsLocationConfiguration get() { return GlobalConfiguration.all().getInstance(JenkinsLocationConfiguration.class); } - + /** * Gets local configuration. For explanation when it could die, see {@link #get()} */ diff --git a/core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java b/core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java index 9c43d68a3411..20531cc55418 100644 --- a/core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java +++ b/core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java @@ -22,6 +22,8 @@ import org.apache.commons.jelly.JellyTagException; import org.apache.commons.jelly.Script; import org.apache.commons.jelly.XMLOutput; +import org.jenkins.ui.icon.Icon; +import org.jenkins.ui.icon.IconSet; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.stapler.HttpResponse; @@ -162,7 +164,7 @@ public ContextMenu add(Node n) { Computer c = n.toComputer(); return add(new MenuItem() .withDisplayName(n.getDisplayName()) - .withStockIcon(c == null ? "computer.png" : c.getIcon()) + .withIconClass(c == null ? "icon-computer" : c.getIconClassName()) .withContextRelativeUrl(n.getSearchUrl())); } @@ -174,7 +176,7 @@ public ContextMenu add(Node n) { public ContextMenu add(Computer c) { return add(new MenuItem() .withDisplayName(c.getDisplayName()) - .withStockIcon(c.getIcon()) + .withIconClass(c.getIconClassName()) .withContextRelativeUrl(c.getUrl())); } @@ -339,7 +341,13 @@ public MenuItem withIcon(BallColor color) { * String like "gear.png" that resolves to 24x24 stock icon in the core */ public MenuItem withStockIcon(String icon) { - this.icon = Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH + "/images/24x24/"+icon; + this.icon = getResourceUrl() + "/images/24x24/" + icon; + return this; + } + + public MenuItem withIconClass(String iconClass) { + Icon iconByClass = IconSet.icons.getIconByClassSpec(iconClass + " icon-md"); + this.icon = iconByClass == null ? null : iconByClass.getQualifiedUrl(getResourceUrl()); return this; } @@ -351,6 +359,11 @@ public MenuItem withDisplayName(String displayName) { public MenuItem withDisplayName(ModelObject o) { return withDisplayName(o.getDisplayName()); } + + private String getResourceUrl() { + return Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH; + } + } /** diff --git a/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java b/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java index 0752b0bcc250..7c87af7924c0 100644 --- a/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java +++ b/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java @@ -92,7 +92,7 @@ */ @SuppressWarnings("unchecked") // AbstractItem.getParent does not correctly override; scheduleBuild2 inherently untypable public abstract class ParameterizedJobMixIn & ParameterizedJobMixIn.ParameterizedJob & Queue.Task, RunT extends Run & Queue.Executable> { - + protected abstract JobT asJob(); /** @see BuildableItem#scheduleBuild() */ diff --git a/core/src/main/java/jenkins/model/item_category/ItemCategory.java b/core/src/main/java/jenkins/model/item_category/ItemCategory.java index 520c98090fa1..d4443273a330 100644 --- a/core/src/main/java/jenkins/model/item_category/ItemCategory.java +++ b/core/src/main/java/jenkins/model/item_category/ItemCategory.java @@ -25,10 +25,10 @@ package jenkins.model.item_category; import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; +import hudson.RestrictedSince; import hudson.model.TopLevelItemDescriptor; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -47,8 +47,8 @@ public abstract class ItemCategory implements ExtensionPoint { * See JENKINS-36593 for more info. */ @Restricted(NoExternalUse.class) - @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "TODO needs triage") - public static int MIN_TOSHOW = 1; + @RestrictedSince("2.14") + public static final int MIN_TOSHOW = 1; /** * Helpful to set the order. diff --git a/core/src/main/java/jenkins/model/lazy/AbstractLazyLoadRunMap.java b/core/src/main/java/jenkins/model/lazy/AbstractLazyLoadRunMap.java index 24be3366bf3c..91e6cf224b69 100644 --- a/core/src/main/java/jenkins/model/lazy/AbstractLazyLoadRunMap.java +++ b/core/src/main/java/jenkins/model/lazy/AbstractLazyLoadRunMap.java @@ -247,7 +247,7 @@ public boolean contains(Object v) { /** * Historical holder for map. - * + * * TODO all this mess including {@link #numberOnDisk} could probably be simplified to a single {@code TreeMap>} * where a null value means not yet loaded and a broken entry just uses {@code NoHolder}. * @@ -317,7 +317,7 @@ public final boolean baseDirInitialized() { public final void updateBaseDir(File dir) { this.dir = dir; } - + /** * Let go of all the loaded references. * @@ -625,7 +625,7 @@ private Index copy() { /** * Tries to load the record #N. - * + * * @return null if the data failed to load. */ private R load(int n, Index editInPlace) { diff --git a/core/src/main/java/jenkins/security/UserDetailsCache.java b/core/src/main/java/jenkins/security/UserDetailsCache.java index b03f5c0da5e3..12538a1da742 100644 --- a/core/src/main/java/jenkins/security/UserDetailsCache.java +++ b/core/src/main/java/jenkins/security/UserDetailsCache.java @@ -64,13 +64,15 @@ public final class UserDetailsCache { @Restricted(NoExternalUse.class) @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "field is static for script console") public UserDetailsCache() { - if (EXPIRE_AFTER_WRITE_SEC == null || EXPIRE_AFTER_WRITE_SEC <= 0) { + Integer expireAfterWriteSec = EXPIRE_AFTER_WRITE_SEC; + if (expireAfterWriteSec == null || expireAfterWriteSec <= 0) { //just in case someone is trying to trick us - EXPIRE_AFTER_WRITE_SEC = SystemProperties.getInteger(SYS_PROP_NAME, (int)TimeUnit.MINUTES.toSeconds(2)); - if (EXPIRE_AFTER_WRITE_SEC <= 0) { + expireAfterWriteSec = SystemProperties.getInteger(SYS_PROP_NAME, (int)TimeUnit.MINUTES.toSeconds(2)); + if (expireAfterWriteSec <= 0) { //The property could also be set to a negative value - EXPIRE_AFTER_WRITE_SEC = (int)TimeUnit.MINUTES.toSeconds(2); + expireAfterWriteSec = (int)TimeUnit.MINUTES.toSeconds(2); } + EXPIRE_AFTER_WRITE_SEC = expireAfterWriteSec; } detailsCache = CacheBuilder.newBuilder().softValues().expireAfterWrite(EXPIRE_AFTER_WRITE_SEC, TimeUnit.SECONDS).build(); existenceCache = CacheBuilder.newBuilder().softValues().expireAfterWrite(EXPIRE_AFTER_WRITE_SEC, TimeUnit.SECONDS).build(); diff --git a/core/src/main/java/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor.java b/core/src/main/java/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor.java index 18827c94fdbd..20c9d27e1b10 100644 --- a/core/src/main/java/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor.java +++ b/core/src/main/java/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitor.java @@ -161,7 +161,12 @@ public boolean hasMoreRecentlyUsedToken(@NonNull User user, ApiTokenProperty.Tok } @RequirePOST - @SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "written to by Stapler") + @SuppressFBWarnings( + value = { + "NP_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", + "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD" + }, + justification = "written to by Stapler") public HttpResponse doRevokeAllSelected(@JsonBody RevokeAllSelectedModel content) throws IOException { for (RevokeAllSelectedUserAndUuid value : content.values) { if (value.userId == null) { diff --git a/core/src/main/java/jenkins/slaves/EncryptedSlaveAgentJnlpFile.java b/core/src/main/java/jenkins/slaves/EncryptedSlaveAgentJnlpFile.java index f4c4e71387c0..1f1f75c6f01a 100644 --- a/core/src/main/java/jenkins/slaves/EncryptedSlaveAgentJnlpFile.java +++ b/core/src/main/java/jenkins/slaves/EncryptedSlaveAgentJnlpFile.java @@ -1,6 +1,5 @@ package jenkins.slaves; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Util; import hudson.security.AccessControlled; import hudson.security.Permission; @@ -40,6 +39,7 @@ public class EncryptedSlaveAgentJnlpFile implements HttpResponse { private static final Logger LOG = Logger.getLogger(EncryptedSlaveAgentJnlpFile.class.getName()); + private static final SecureRandom RANDOM = new SecureRandom(); /** * The object that owns the Jelly view that renders JNLP file. @@ -69,7 +69,6 @@ public EncryptedSlaveAgentJnlpFile(AccessControlled it, String viewName, String this.slaveName = slaveName; } - @SuppressFBWarnings(value = "DMI_RANDOM_USED_ONLY_ONCE", justification = "TODO needs triage") @Override public void generateResponse(StaplerRequest req, final StaplerResponse res, Object node) throws IOException, ServletException { RequestDispatcher view = req.getView(it, viewName); @@ -86,7 +85,7 @@ public void generateResponse(StaplerRequest req, final StaplerResponse res, Obje view.forward(req, temp); byte[] iv = new byte[128/8]; - new SecureRandom().nextBytes(iv); + RANDOM.nextBytes(iv); byte[] jnlpMac; if(it instanceof SlaveComputer) { diff --git a/core/src/main/java/jenkins/util/ProgressiveRendering.java b/core/src/main/java/jenkins/util/ProgressiveRendering.java index 3a29ea71ab09..3bfbf2cf82b2 100644 --- a/core/src/main/java/jenkins/util/ProgressiveRendering.java +++ b/core/src/main/java/jenkins/util/ProgressiveRendering.java @@ -102,7 +102,6 @@ protected ProgressiveRendering() { /** * For internal use. */ - @SuppressWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE") @JavaScriptMethod public final void start() { Ancestor ancestor = Stapler.getCurrentRequest().findAncestor(BoundObjectTable.class); if (ancestor == null) { diff --git a/core/src/main/java/jenkins/util/SystemProperties.java b/core/src/main/java/jenkins/util/SystemProperties.java index bb1b51fc47d3..5e6381d5e29b 100644 --- a/core/src/main/java/jenkins/util/SystemProperties.java +++ b/core/src/main/java/jenkins/util/SystemProperties.java @@ -87,6 +87,7 @@ private interface Handler { private static final Handler NULL_HANDLER = key -> null; + @SuppressFBWarnings(value = "NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", justification = "the field is initialized by a static initializer, not a constructor") private static @NonNull Handler handler = NULL_HANDLER; // declared in WEB-INF/web.xml diff --git a/core/src/main/java/jenkins/util/TreeString.java b/core/src/main/java/jenkins/util/TreeString.java index b9970b60f665..fb60151aa405 100644 --- a/core/src/main/java/jenkins/util/TreeString.java +++ b/core/src/main/java/jenkins/util/TreeString.java @@ -43,8 +43,6 @@ * @author Kohsuke Kawaguchi * @since 1.473 */ -// CHECKSTYLE:OFF -@SuppressWarnings("PMD") public final class TreeString implements Serializable { private static final long serialVersionUID = 3621959682117480904L; @@ -191,7 +189,6 @@ public static TreeString of(final String s) { * Default {@link Converter} implementation for XStream that does interning * scoped to one unmarshalling. */ - @SuppressWarnings("all") public static final class ConverterImpl implements Converter { public ConverterImpl(final XStream xs) {} diff --git a/core/src/main/java/jenkins/util/TreeStringBuilder.java b/core/src/main/java/jenkins/util/TreeStringBuilder.java index 78effcb5f570..a04dc638e332 100644 --- a/core/src/main/java/jenkins/util/TreeStringBuilder.java +++ b/core/src/main/java/jenkins/util/TreeStringBuilder.java @@ -20,8 +20,6 @@ * @author Kohsuke Kawaguchi * @since 1.473 */ -@SuppressWarnings({"PMD", "all"}) -//CHECKSTYLE:OFF public class TreeStringBuilder { Child root = new Child(new TreeString()); diff --git a/core/src/main/java/jenkins/views/FullHeader.java b/core/src/main/java/jenkins/views/FullHeader.java index aef4537bdbf0..1ede5645dff4 100644 --- a/core/src/main/java/jenkins/views/FullHeader.java +++ b/core/src/main/java/jenkins/views/FullHeader.java @@ -3,13 +3,13 @@ /** * {@link Header} that provides its own resources as full replacement. It does not * depends on any core resource (images, CSS, JS, etc.) - * + * * Given this kind of header is totally independent, it will be compatible by default. - * + * * @see Header */ public abstract class FullHeader extends Header { - + public boolean isCompatible() { return true; } diff --git a/core/src/main/java/org/jenkins/ui/icon/Icon.java b/core/src/main/java/org/jenkins/ui/icon/Icon.java index 3162ea222c2c..616e60d1076f 100644 --- a/core/src/main/java/org/jenkins/ui/icon/Icon.java +++ b/core/src/main/java/org/jenkins/ui/icon/Icon.java @@ -179,7 +179,23 @@ public String getUrl() { */ public String getQualifiedUrl(JellyContext context) { if (url != null) { - return iconType.toQualifiedUrl(url, context); + return iconType.toQualifiedUrl(url, context.getVariable("resURL").toString()); + } else { + return ""; + } + } + + /** + * Get the qualified icon url. + *
    + * Qualifying the URL involves prefixing it depending on whether the icon is a core or plugin icon. + * + * @param resUrl The url of resources. + * @return The qualified icon url. + */ + public String getQualifiedUrl(String resUrl) { + if (url != null) { + return iconType.toQualifiedUrl(url, resUrl); } else { return ""; } diff --git a/core/src/main/java/org/jenkins/ui/icon/IconType.java b/core/src/main/java/org/jenkins/ui/icon/IconType.java index 54b2cdba3331..462b0ee1f2a9 100644 --- a/core/src/main/java/org/jenkins/ui/icon/IconType.java +++ b/core/src/main/java/org/jenkins/ui/icon/IconType.java @@ -23,8 +23,6 @@ */ package org.jenkins.ui.icon; -import org.apache.commons.jelly.JellyContext; - /** * Icon type. * @@ -41,11 +39,10 @@ public enum IconType { * Qualifying the URL involves prefixing it depending on whether the icon is a core or plugin icon. * * @param url The url to be qualified. - * @param context The JellyContext. + * @param resURL The url of resources. * @return The qualified icon url. */ - public String toQualifiedUrl(String url, JellyContext context) { - String resURL = context.getVariable("resURL").toString(); + public String toQualifiedUrl(String url, String resURL) { switch (this) { case CORE: { diff --git a/core/src/main/resources/hudson/logging/Messages.properties b/core/src/main/resources/hudson/logging/Messages.properties index 2ec0a4891708..cdac5ab4f965 100644 --- a/core/src/main/resources/hudson/logging/Messages.properties +++ b/core/src/main/resources/hudson/logging/Messages.properties @@ -22,3 +22,5 @@ LogRecorderManager.init=Initializing log recorders LogRecorderManager.DisplayName=System Log +LogRecorderManager.LoggerNotFound=A logger named "{0}" does not exist. \ + Add a logger by this name to a log recorder before attempting to configure its level. diff --git a/core/src/main/resources/lib/hudson/executors.jelly b/core/src/main/resources/lib/hudson/executors.jelly index c63b0210aca2..440fe18d0f4e 100644 --- a/core/src/main/resources/lib/hudson/executors.jelly +++ b/core/src/main/resources/lib/hudson/executors.jelly @@ -39,10 +39,10 @@ THE SOFTWARE. - ( ${%offline}) + ( ${%offline}) - (${%launching}) + (${%launching}) (${%offline}) diff --git a/core/src/test/java/hudson/FilePathTest.java b/core/src/test/java/hudson/FilePathTest.java index 3b644e7f3dfe..eb42d487fb8f 100644 --- a/core/src/test/java/hudson/FilePathTest.java +++ b/core/src/test/java/hudson/FilePathTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Alan Harder - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -140,9 +140,9 @@ public class FilePathTest { final File tmp = temp.newFile(); int fileSize = 90000; - + givenSomeContentInFile(tmp, fileSize); - + List> results = whenFileIsCopied100TimesConcurrently(tmp); // THEN copied count was always equal the expected size @@ -158,7 +158,7 @@ private void givenSomeContentInFile(File file, int size) throws IOException { os.write(buf); } } - + private List> whenFileIsCopied100TimesConcurrently(final File file) throws InterruptedException { List> r = new ArrayList<>(); for (int i=0; i<100; i++) { @@ -342,17 +342,17 @@ private FilePath createFilePath(final File base, final String... path) throws IO FileUtils.touch(building); return new FilePath(building); } - + /** * Performs round-trip archiving for Tar handling methods. * @throws Exception test failure */ @Test public void compressTarUntarRoundTrip() throws Exception { - checkTarUntarRoundTrip("compressTarUntarRoundTrip_zero", 0); - checkTarUntarRoundTrip("compressTarUntarRoundTrip_small", 100); - checkTarUntarRoundTrip("compressTarUntarRoundTrip_medium", 50000); + checkTarUntarRoundTrip("compressTarUntarRoundTrip_zero", 0); + checkTarUntarRoundTrip("compressTarUntarRoundTrip_small", 100); + checkTarUntarRoundTrip("compressTarUntarRoundTrip_medium", 50000); } - + /** * Checks that big files (greater than 8GB) can be archived and then unpacked. * This test is disabled by default due the impact on RAM. @@ -366,7 +366,7 @@ private FilePath createFilePath(final File base, final String... path) throws IO final String filePrefix = "JENKINS-10629"; checkTarUntarRoundTrip(filePrefix, largeFileSize); } - + private void checkTarUntarRoundTrip(String filePrefix, long fileSize) throws Exception { final File tmpDir = temp.newFolder(filePrefix); final File tempFile = new File(tmpDir, filePrefix + ".log"); @@ -436,13 +436,13 @@ private void checkTarUntarRoundTrip(String filePrefix, long fileSize) throws Exc FilePath middle = new FilePath(base, "jdk/jdk1.6.0_21/label/sqlserver/profile/sqlserver"); FilePath full = new FilePath(middle, "acceptance-tests\\distribution.zip"); assertFalse(full.isUnix()); - - + + FilePath unixPath = new FilePath(dummy, "/home/test"); assertTrue(unixPath.isUnix()); } - + /** * Tests that permissions are kept when using {@link FilePath#copyToWithPermission(FilePath)}. * Also tries to check that a problem with setting the last-modified date on Windows doesn't fail the whole copy @@ -453,21 +453,21 @@ private void checkTarUntarRoundTrip(String filePrefix, long fileSize) throws Exc File child = new File(tmp,"child"); FilePath childP = new FilePath(child); childP.touch(4711); - + Chmod chmodTask = new Chmod(); chmodTask.setProject(new Project()); chmodTask.setFile(child); chmodTask.setPerm("0400"); chmodTask.execute(); - + FilePath copy = new FilePath(channels.british, tmp.getPath()).child("copy"); childP.copyToWithPermission(copy); - + assertEquals(childP.mode(),copy.mode()); if (!Functions.isWindows()) { assertEquals(childP.lastModified(),copy.lastModified()); } - + // JENKINS-11073: // Windows seems to have random failures when setting the timestamp on newly generated // files. So test that: @@ -504,7 +504,7 @@ private void checkTarUntarRoundTrip(String filePrefix, long fileSize) throws Exc in.mkdirs(); in.child("c").touch(0); in.child("b").symlinkTo("c", TaskListener.NULL); - + FilePath tar = tmp.child("test.tar"); in.tar(tar.write(), "**/*"); @@ -566,7 +566,7 @@ private static void assertValidateAntFileMask(String expected, FilePath d, Strin assertEquals(Messages.FilePath_validateAntFileMask_portionMatchButPreviousNotMatchAndSuggest("**/*.js", "**", "**/*.js"), d.validateAntFileMask("**/*.js", 1000)); assertThrows(InterruptedException.class, () -> d.validateAntFileMask("**/*.js", 10)); } - + @Issue("JENKINS-5253") @Test public void testValidateCaseSensitivity() throws Exception { File tmp = Util.createTempDir(); @@ -585,27 +585,27 @@ private static void assertValidateAntFileMask(String expected, FilePath d, Strin Util.deleteRecursive(tmp); } } - + @Issue("JENKINS-15418") @Test public void deleteLongPathOnWindows() throws Exception { File tmp = temp.getRoot(); FilePath d = new FilePath(channels.french, tmp.getPath()); - + // construct a very long path StringBuilder sb = new StringBuilder(); while(sb.length() + tmp.getPath().length() < 260 - "very/".length()) { sb.append("very/"); } sb.append("pivot/very/very/long/path"); - - FilePath longPath = d.child(sb.toString()); + + FilePath longPath = d.child(sb.toString()); longPath.mkdirs(); FilePath childInLongPath = longPath.child("file.txt"); childInLongPath.touch(0); - + File firstDirectory = new File(tmp.getAbsolutePath() + "/very"); Util.deleteRecursive(firstDirectory); - + assertFalse("Could not delete directory!", firstDirectory.exists()); } @@ -723,7 +723,7 @@ private InputStream someZippedContent() throws IOException { final FilePath src = new FilePath(sub); final FilePath dst = new FilePath(top); - + // test conflict subdir src.moveAllChildrenTo(dst); } @@ -828,7 +828,7 @@ public void deleteSuffixesRecursive() throws Exception { FilePath textTempFile = suffix.createTextTempFile("tmp", null, "dummy", true); assertThat(textTempFile.exists(), is(true)); - + filePath.deleteSuffixesRecursive(); assertThat(textTempFile.exists(), is(false)); } diff --git a/core/src/test/java/hudson/FunctionsTest.java b/core/src/test/java/hudson/FunctionsTest.java index 5309f87068aa..3342c30ccac4 100644 --- a/core/src/test/java/hudson/FunctionsTest.java +++ b/core/src/test/java/hudson/FunctionsTest.java @@ -124,7 +124,7 @@ public void testGetActionUrl_relativePath() { } } } - + @Test public void testGetRelativeLinkTo_JobContainedInView() { String contextPath = "/jenkins"; @@ -187,9 +187,9 @@ public void testGetRelativeLinkTo_JobNotContainedInView() { assertEquals("/jenkins/job/i/", result); } } - + private interface TopLevelItemAndItemGroup extends TopLevelItem, ItemGroup, ViewGroup {} - + @Test public void testGetRelativeLinkTo_JobContainedInViewWithinItemGroup() { String contextPath = "/jenkins"; @@ -240,7 +240,7 @@ public void testGetRelativeDisplayName() { when(i.getFullDisplayName()).thenReturn("displayName"); assertEquals("displayName",Functions.getRelativeDisplayNameFrom(i, null)); } - + @Test public void testGetRelativeDisplayNameInsideItemGroup() { Item i = mock(Item.class); @@ -265,7 +265,7 @@ private void createMockAncestors(StaplerRequest req, Ancestor... ancestors) { List ancestorsList = Arrays.asList(ancestors); when(req.getAncestors()).thenReturn(ancestorsList); } - + private TopLevelItem createMockItem(ItemGroup p, String shortUrl) { return createMockItem(p, shortUrl, shortUrl); } @@ -283,7 +283,7 @@ private Jenkins createMockJenkins(MockedStatic mockedJenkins) { mockedJenkins.when(Jenkins::get).thenReturn(j); return j; } - + private static Ancestor createAncestor(Object o, String relativePath) { Ancestor a = mock(Ancestor.class); when(a.getObject()).thenReturn(o); diff --git a/core/src/test/java/hudson/PluginManagerTest.java b/core/src/test/java/hudson/PluginManagerTest.java index 9fcb0310d55d..71161bb9490d 100644 --- a/core/src/test/java/hudson/PluginManagerTest.java +++ b/core/src/test/java/hudson/PluginManagerTest.java @@ -87,42 +87,42 @@ public void parseInvalidRequestedPlugins() throws Exception { assertThat(ex.getCause(), instanceOf(SAXException.class)); assertThat(ex.getCause().getMessage(), containsString("DOCTYPE is disallowed")); } - + @Test public void shouldProperlyParseManifestFromJar() throws IOException { File jar = createHpiWithManifest(); final Manifest manifest = PluginManager.parsePluginManifest(jar.toURI().toURL()); - + assertThat("manifest should have been read from the sample", manifest, notNullValue()); assertAttribute(manifest, "Created-By", "Apache Maven"); assertAttribute(manifest, "Short-Name", "matrix-auth"); - + // Multi-line entries assertAttribute(manifest, "Specification-Title", "Offers matrix-based security authorization strategies (global and per-project)."); assertAttribute(manifest, "Url", "http://wiki.jenkins-ci.org/display/JENKINS/Matrix+Authorization+Strategy+Plugin"); - + // Empty field assertAttribute(manifest, "Plugin-Developers", null); } - + @Test public void shouldProperlyRetrieveModificationDate() throws IOException { File jar = createHpiWithManifest(); URL url = toManifestUrl(jar); - assertThat("Manifest last modified date should be equal to the file date", - PluginManager.getModificationDate(url), + assertThat("Manifest last modified date should be equal to the file date", + PluginManager.getModificationDate(url), equalTo(jar.lastModified())); } - + private static void assertAttribute(Manifest manifest, String attributeName, String value) { Attributes attributes = manifest.getMainAttributes(); assertThat("Main attributes must not be empty", attributes, notNullValue()); - assertThat("Attribute '" + attributeName + "' does not match the sample", - attributes.getValue(attributeName), + assertThat("Attribute '" + attributeName + "' does not match the sample", + attributes.getValue(attributeName), equalTo(value)); - + } - + private static final String SAMPLE_MANIFEST_FILE = "Manifest-Version: 1.0\n" + "Archiver-Version: Plexus Archiver\n" + "Created-By: Apache Maven\n" + @@ -146,12 +146,12 @@ private static void assertAttribute(Manifest manifest, String attributeName, Str "Plugin-Dependencies: icon-shim:2.0.3,cloudbees-folder:5.2.2;resolution\n" + " :=optional\n" + "Plugin-Developers: "; - + private File createHpiWithManifest() throws IOException { String manifestPath = "META-INF/MANIFEST.MF"; new File("META-INF").mkdir(); FileUtils.write(new File(tmp.toFile(), manifestPath), SAMPLE_MANIFEST_FILE, StandardCharsets.UTF_8); - + final File f = new File(tmp.toFile(), "my.hpi"); try(ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(f.toPath()))) { ZipEntry e = new ZipEntry(manifestPath); @@ -162,10 +162,10 @@ private File createHpiWithManifest() throws IOException { } return f; } - - + + private URL toManifestUrl(File jarFile) throws MalformedURLException { final String manifestPath = "META-INF/MANIFEST.MF"; return new URL("jar:" + jarFile.toURI().toURL() + "!/" + manifestPath); - } + } } diff --git a/core/src/test/java/hudson/PluginWrapperTest.java b/core/src/test/java/hudson/PluginWrapperTest.java index 0a0e51a588ff..9b7842e4a6b8 100644 --- a/core/src/test/java/hudson/PluginWrapperTest.java +++ b/core/src/test/java/hudson/PluginWrapperTest.java @@ -36,7 +36,7 @@ public class PluginWrapperTest { private static Locale loc; - + @BeforeAll public static void before() { Jenkins.VERSION = "2.0"; // Some value needed - tests will overwrite if necessary @@ -50,7 +50,7 @@ public static void after() { Locale.setDefault(loc); } } - + @Test public void dependencyTest() { String version = "plugin:0.0.2"; @@ -131,7 +131,7 @@ private void assertInjectingJarsWorks(ClassLoader cl) throws Exception { assertThat("expect one more element from the updated classloader", e2size - e1size, is(1)); } - + private void assertContains(Throwable ex, String... patterns) { String msg = ex.getMessage(); for (String pattern : patterns) { diff --git a/core/src/test/java/hudson/UtilTest.java b/core/src/test/java/hudson/UtilTest.java index 253b7b7a326d..2eed7e9c866b 100644 --- a/core/src/test/java/hudson/UtilTest.java +++ b/core/src/test/java/hudson/UtilTest.java @@ -100,7 +100,7 @@ public void testReplaceMacro() { assertEquals("a.B", Util.replaceMacro("$A.B", m)); assertEquals("a-b", Util.replaceMacro("${A.B}", m)); - // test that more complex scenarios work + // test that more complex scenarios work assertEquals("/a/B/aa", Util.replaceMacro("/$A/$B/$AA",m)); assertEquals("a-aa", Util.replaceMacro("$A-$AA",m)); assertEquals("/a/foo/can/B/you-believe_aa~it?", Util.replaceMacro("/$A/foo/can/$B/you-believe_$AA~it?",m)); @@ -354,50 +354,50 @@ public void testHtmlEscape() { @Issue("JENKINS-10346") @Test public void testDigestThreadSafety() throws InterruptedException { - String a = "abcdefgh"; - String b = "123456789"; + String a = "abcdefgh"; + String b = "123456789"; - String digestA = Util.getDigestOf(a); - String digestB = Util.getDigestOf(b); + String digestA = Util.getDigestOf(a); + String digestB = Util.getDigestOf(b); - DigesterThread t1 = new DigesterThread(a, digestA); - DigesterThread t2 = new DigesterThread(b, digestB); + DigesterThread t1 = new DigesterThread(a, digestA); + DigesterThread t2 = new DigesterThread(b, digestB); - t1.start(); - t2.start(); + t1.start(); + t2.start(); - t1.join(); - t2.join(); + t1.join(); + t2.join(); - if (t1.error != null) { - fail(t1.error); - } - if (t2.error != null) { - fail(t2.error); - } + if (t1.error != null) { + fail(t1.error); + } + if (t2.error != null) { + fail(t2.error); + } } private static class DigesterThread extends Thread { - private String string; - private String expectedDigest; - - private String error; - - DigesterThread(String string, String expectedDigest) { - this.string = string; - this.expectedDigest = expectedDigest; - } - - @Override - public void run() { - for (int i=0; i < 1000; i++) { - String digest = Util.getDigestOf(this.string); - if (!this.expectedDigest.equals(digest)) { - this.error = "Expected " + this.expectedDigest + ", but got " + digest; - break; - } - } - } + private String string; + private String expectedDigest; + + private String error; + + DigesterThread(String string, String expectedDigest) { + this.string = string; + this.expectedDigest = expectedDigest; + } + + @Override + public void run() { + for (int i=0; i < 1000; i++) { + String digest = Util.getDigestOf(this.string); + if (!this.expectedDigest.equals(digest)) { + this.error = "Expected " + this.expectedDigest + ", but got " + digest; + break; + } + } + } } @Test diff --git a/core/src/test/java/hudson/XmlFileTest.java b/core/src/test/java/hudson/XmlFileTest.java index 49a1dbb9f2ca..dc4936b73f2e 100644 --- a/core/src/test/java/hudson/XmlFileTest.java +++ b/core/src/test/java/hudson/XmlFileTest.java @@ -58,7 +58,7 @@ public void canReadXml1_1Test() throws IOException { assertThat(n.getMode().toString(), is("NORMAL")); } } - + @Test public void canReadXmlWithControlCharsTest() throws IOException { URL configUrl = getClass().getResource("/hudson/config_1_1_with_special_chars.xml"); diff --git a/core/src/test/java/hudson/console/UrlAnnotatorTest.java b/core/src/test/java/hudson/console/UrlAnnotatorTest.java index 2db878c4326f..c5a32f7c4d8f 100644 --- a/core/src/test/java/hudson/console/UrlAnnotatorTest.java +++ b/core/src/test/java/hudson/console/UrlAnnotatorTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Alan Harder - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/test/java/hudson/model/AbstractItemTest.java b/core/src/test/java/hudson/model/AbstractItemTest.java index 2be49a527e55..e03d89207af6 100644 --- a/core/src/test/java/hudson/model/AbstractItemTest.java +++ b/core/src/test/java/hudson/model/AbstractItemTest.java @@ -26,16 +26,16 @@ protected StubAbstractItem() { public Collection getAllJobs() { return null; } - + /** * Override save so that nothing happens when setDisplayName() is called */ @Override public void save() { - + } } - + @Test public void testSetDisplayName() throws Exception { final String displayName = "testDisplayName"; @@ -43,7 +43,7 @@ public void testSetDisplayName() throws Exception { i.setDisplayName(displayName); assertEquals(displayName, i.getDisplayName()); } - + @Test public void testGetDefaultDisplayName() { final String name = "the item name"; @@ -51,18 +51,18 @@ public void testGetDefaultDisplayName() { i.doSetName(name); // assert that if the displayname is not set, the name is actually returned assertEquals(name, i.getDisplayName()); - + } - + @Test public void testSearchNameIsName() { final String name = "the item name jlrtlekjtekrjkjr"; StubAbstractItem i = new StubAbstractItem(); i.doSetName(name); - + assertEquals(i.getName(), i.getSearchName()); } - + @Test public void testGetDisplayNameOrNull() throws Exception { final String projectName = "projectName"; @@ -71,7 +71,7 @@ public void testGetDisplayNameOrNull() throws Exception { i.doSetName(projectName); assertEquals(projectName, i.getName()); assertNull(i.getDisplayNameOrNull()); - + i.setDisplayName(displayName); assertEquals(displayName, i.getDisplayNameOrNull()); } diff --git a/core/src/test/java/hudson/model/BuildStatusSummaryTest.java b/core/src/test/java/hudson/model/BuildStatusSummaryTest.java index 8b66e6835249..2685beae2720 100644 --- a/core/src/test/java/hudson/model/BuildStatusSummaryTest.java +++ b/core/src/test/java/hudson/model/BuildStatusSummaryTest.java @@ -12,7 +12,7 @@ /** * Tests {@link Run#getBuildStatusSummary()}. - * + * * @author kutzi */ @SuppressWarnings("rawtypes") @@ -25,132 +25,132 @@ public class BuildStatusSummaryTest { public void before() { mockBuilds(Run.class); } - + private void mockBuilds(Class buildClass) { this.build = mock(buildClass); this.prevBuild = mock(buildClass); - + when(this.build.getPreviousBuild()).thenReturn(prevBuild); - + when(this.build.getBuildStatusSummary()).thenCallRealMethod(); } - + @Test public void testStatusUnknownIfRunIsStillBuilding() { when(this.build.getResult()).thenReturn(null); when(this.build.isBuilding()).thenReturn(true); - + Summary summary = this.build.getBuildStatusSummary(); assertEquals(Messages.Run_Summary_Unknown(), summary.message); } - + @Test public void testSuccess() { when(this.build.getResult()).thenReturn(Result.SUCCESS); when(this.prevBuild.getResult()).thenReturn(Result.SUCCESS); - + Summary summary = this.build.getBuildStatusSummary(); assertFalse(summary.isWorse); assertEquals(Messages.Run_Summary_Stable(), summary.message); - + // same if there is no previous build when(this.build.getPreviousBuild()).thenReturn(null); summary = this.build.getBuildStatusSummary(); assertFalse(summary.isWorse); assertEquals(Messages.Run_Summary_Stable(), summary.message); - + // from NOT_BUILD should also mean normal success and not 'back to normal' when(this.prevBuild.getResult()).thenReturn(Result.NOT_BUILT); - + summary = this.build.getBuildStatusSummary(); assertFalse(summary.isWorse); assertEquals(Messages.Run_Summary_Stable(), summary.message); - - + + // same if previous one was aborted when(this.prevBuild.getResult()).thenReturn(Result.ABORTED); - + summary = this.build.getBuildStatusSummary(); assertFalse(summary.isWorse); assertEquals(Messages.Run_Summary_Stable(), summary.message); } - + @Test public void testFixed() { when(this.build.getResult()).thenReturn(Result.SUCCESS); when(this.prevBuild.getResult()).thenReturn(Result.FAILURE); - + Summary summary = this.build.getBuildStatusSummary(); - + assertFalse(summary.isWorse); assertEquals(Messages.Run_Summary_BackToNormal(), summary.message); - + // same from unstable: when(this.prevBuild.getResult()).thenReturn(Result.UNSTABLE); - + summary = this.build.getBuildStatusSummary(); - + assertFalse(summary.isWorse); assertEquals(Messages.Run_Summary_BackToNormal(), summary.message); } - + @Test public void testFailure() { when(this.build.getResult()).thenReturn(Result.FAILURE); when(this.prevBuild.getResult()).thenReturn(Result.FAILURE); - + Summary summary = this.build.getBuildStatusSummary(); - + assertFalse(summary.isWorse); assertEquals(Messages.Run_Summary_BrokenForALongTime(), summary.message); } - + @Test public void testBecameFailure() { when(this.build.getResult()).thenReturn(Result.FAILURE); when(this.prevBuild.getResult()).thenReturn(Result.SUCCESS); when(this.build.getPreviousNotFailedBuild()).thenReturn(this.prevBuild); - + Summary summary = this.build.getBuildStatusSummary(); - + assertTrue(summary.isWorse); assertEquals(Messages.Run_Summary_BrokenSinceThisBuild(), summary.message); } - + @Test public void testFailureSince() { when(this.build.getResult()).thenReturn(Result.FAILURE); when(this.prevBuild.getResult()).thenReturn(Result.FAILURE); when(this.prevBuild.getDisplayName()).thenReturn("prevBuild"); - + Run prevPrevBuild = mock(Run.class); when(prevPrevBuild.getNextBuild()).thenReturn(prevBuild); - when(this.build.getPreviousNotFailedBuild()).thenReturn(prevPrevBuild); - + when(this.build.getPreviousNotFailedBuild()).thenReturn(prevPrevBuild); + Summary summary = this.build.getBuildStatusSummary(); - + assertFalse(summary.isWorse); assertEquals(Messages.Run_Summary_BrokenSince(this.prevBuild.getDisplayName()), summary.message); } - + @Test public void testBecameUnstable() { when(this.build.getResult()).thenReturn(Result.UNSTABLE); when(this.prevBuild.getResult()).thenReturn(Result.SUCCESS); - + Summary summary = this.build.getBuildStatusSummary(); - + assertTrue(summary.isWorse); //assertEquals(Messages.Run_Summary_Stable(), summary.message); } - + @Test public void testUnstableAfterFailure() { when(this.build.getResult()).thenReturn(Result.UNSTABLE); when(this.prevBuild.getResult()).thenReturn(Result.FAILURE); - + Summary summary = this.build.getBuildStatusSummary(); - + assertFalse(summary.isWorse); assertEquals(Messages.Run_Summary_Unstable(), summary.message); } @@ -159,40 +159,40 @@ public void testUnstableAfterFailure() { public void testNonTestRelatedUnstable() { when(this.build.getResult()).thenReturn(Result.UNSTABLE); when(this.prevBuild.getResult()).thenReturn(Result.UNSTABLE); - + Summary summary = this.build.getBuildStatusSummary(); - + assertFalse(summary.isWorse); assertEquals(Messages.Run_Summary_Unstable(), summary.message); } - + @Test public void testNonTestRelatedBecameUnstable() { when(this.build.getResult()).thenReturn(Result.UNSTABLE); when(this.prevBuild.getResult()).thenReturn(Result.SUCCESS); - + Summary summary = this.build.getBuildStatusSummary(); - + assertTrue(summary.isWorse); //assertEquals(Messages.Run_Summary_Unstable(), summary.message); } - + @Test public void testAborted() { when(this.build.getResult()).thenReturn(Result.ABORTED); Summary summary = this.build.getBuildStatusSummary(); - + assertFalse(summary.isWorse); assertEquals(Messages.Run_Summary_Aborted(), summary.message); } - + @Test public void testNotBuilt() { when(this.build.getResult()).thenReturn(Result.NOT_BUILT); Summary summary = this.build.getBuildStatusSummary(); - + assertFalse(summary.isWorse); assertEquals(Messages.Run_Summary_NotBuilt(), summary.message); } - + } diff --git a/core/src/test/java/hudson/model/DisplayNameListenerTest.java b/core/src/test/java/hudson/model/DisplayNameListenerTest.java index 0bf74dbdc828..fbf3cbc196ba 100644 --- a/core/src/test/java/hudson/model/DisplayNameListenerTest.java +++ b/core/src/test/java/hudson/model/DisplayNameListenerTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2011, Yahoo!, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -38,10 +38,10 @@ public void testOnCopied() throws Exception { StubJob dest = new StubJob(); dest.doSetName("dest"); dest.setDisplayName("this should be cleared"); - + // make sure the displayname and the name are different at this point assertNotEquals(dest.getName(), dest.getDisplayName()); - + listener.onCopied(src, dest); // make sure the displayname is equals to the name as it should be null assertEquals(dest.getName(), dest.getDisplayName()); @@ -52,12 +52,12 @@ public void testOnRenamedOldNameEqualsDisplayName() throws Exception { DisplayNameListener listener = new DisplayNameListener(); final String oldName = "old job name"; final String newName = "new job name"; - StubJob src = new StubJob(); + StubJob src = new StubJob(); src.doSetName(newName); src.setDisplayName(oldName); - + listener.onRenamed(src, oldName, newName); - + assertEquals(newName, src.getDisplayName()); } @@ -67,12 +67,12 @@ public void testOnRenamedOldNameNotEqualDisplayName() throws Exception { final String oldName = "old job name"; final String newName = "new job name"; final String displayName = "the display name"; - StubJob src = new StubJob(); + StubJob src = new StubJob(); src.doSetName(newName); src.setDisplayName(displayName); - + listener.onRenamed(src, oldName, oldName); - + // make sure displayname is still intact assertEquals(displayName, src.getDisplayName()); } diff --git a/core/src/test/java/hudson/model/FileParameterValueTest.java b/core/src/test/java/hudson/model/FileParameterValueTest.java index 0b079da122be..11f3d0f00072 100644 --- a/core/src/test/java/hudson/model/FileParameterValueTest.java +++ b/core/src/test/java/hudson/model/FileParameterValueTest.java @@ -36,29 +36,29 @@ * @author Oleg Nenashev */ public class FileParameterValueTest { - + @Issue("JENKINS-19017") @Test public void compareParamsWithSameName() { final String paramName = "MY_FILE_PARAM"; // Same paramName (location) reproduces the bug final FileParameterValue param1 = new FileParameterValue(paramName, new File("ws_param1.txt"), "param1.txt"); final FileParameterValue param2 = new FileParameterValue(paramName, new File("ws_param2.txt"), "param2.txt"); - + assertNotEquals("Files with same locations should be considered as different", param1, param2); assertNotEquals("Files with same locations should be considered as different", param2, param1); } - + @Test public void compareNullParams() { - final String paramName = "MY_FILE_PARAM"; + final String paramName = "MY_FILE_PARAM"; FileParameterValue nonNullParam = new FileParameterValue(paramName, new File("ws_param1.txt"), "param1.txt"); FileParameterValue nullParam1 = new FileParameterValue(null, new File("null_param1.txt"), "null_param1.txt"); FileParameterValue nullParam2 = new FileParameterValue(null, new File("null_param2.txt"), "null_param2.txt"); - + // Combine nulls assertEquals(nullParam1, nullParam1); assertEquals(nullParam1, nullParam2); assertEquals(nullParam2, nullParam1); assertEquals(nullParam2, nullParam2); - + // Compare with non-null assertNotEquals(nullParam1, nonNullParam); assertNotEquals(nonNullParam, nullParam1); diff --git a/core/src/test/java/hudson/model/FingerprintTest.java b/core/src/test/java/hudson/model/FingerprintTest.java index d7fd806e4721..edad87581fe3 100644 --- a/core/src/test/java/hudson/model/FingerprintTest.java +++ b/core/src/test/java/hudson/model/FingerprintTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -45,7 +45,7 @@ public class FingerprintTest { @Rule public TemporaryFolder tmp = new TemporaryFolder(); - + @Test public void rangeSet() { RangeSet rs = new RangeSet(); assertFalse(rs.includes(0)); diff --git a/core/src/test/java/hudson/model/ParametersActionTest.java b/core/src/test/java/hudson/model/ParametersActionTest.java index d7dab81e8c4d..bc2c2bd64fcc 100644 --- a/core/src/test/java/hudson/model/ParametersActionTest.java +++ b/core/src/test/java/hudson/model/ParametersActionTest.java @@ -84,35 +84,35 @@ public void createUpdatedShouldReturnNewInstanceWithNullOverride() { assertNotSame(baseParamsAB, params); } - + @Test @Issue("JENKINS-15094") public void checkNullParameterValues() { SubTask subtask = mock(SubTask.class); Build build = mock(Build.class); - + // Prepare parameters Action StringParameterValue A = new StringParameterValue("A", "foo"); StringParameterValue B = new StringParameterValue("B", "bar"); ParametersAction parametersAction = new ParametersAction(A, null, B); ParametersAction parametersAction2 = new ParametersAction(A,null); - + // Non existent parameter - assertNull(parametersAction.getParameter("C")); + assertNull(parametersAction.getParameter("C")); assertNull(parametersAction.getAssignedLabel(subtask)); - + // Interaction with build EnvVars vars = new EnvVars(); parametersAction.buildEnvironment(build, vars); - assertEquals(2, vars.size()); + assertEquals(2, vars.size()); parametersAction.createVariableResolver(build); - + List wrappers = new ArrayList<>(); parametersAction.createBuildWrappers(build, wrappers); assertEquals(0, wrappers.size()); - + // Merges and overrides assertEquals(3, parametersAction.createUpdated(parametersAction2.getParameters()).getParameters().size()); - assertEquals(3, parametersAction.merge(parametersAction2).getParameters().size()); + assertEquals(3, parametersAction.merge(parametersAction2).getParameters().size()); } } diff --git a/core/src/test/java/hudson/model/RunParameterValueTest.java b/core/src/test/java/hudson/model/RunParameterValueTest.java index 18c5b088ab1f..8b809d6619c8 100644 --- a/core/src/test/java/hudson/model/RunParameterValueTest.java +++ b/core/src/test/java/hudson/model/RunParameterValueTest.java @@ -31,7 +31,7 @@ import org.junit.Test; public class RunParameterValueTest { - + @SuppressWarnings("ResultOfObjectAllocationIgnored") @Test public void robustness() { RunParameterValue rpv = new RunParameterValue("whatever", "folder/job#57"); diff --git a/core/src/test/java/hudson/model/UserTest.java b/core/src/test/java/hudson/model/UserTest.java index 96e874466ea9..6995f3ea69da 100644 --- a/core/src/test/java/hudson/model/UserTest.java +++ b/core/src/test/java/hudson/model/UserTest.java @@ -35,7 +35,7 @@ * @author Oleg Nenashev */ public class UserTest { - + @Test @Issue("JENKINS-33600") public void blankIdsOrFullNamesShouldNotBeAllowed() { @@ -43,7 +43,7 @@ public void blankIdsOrFullNamesShouldNotBeAllowed() { assertThat("Empty user IDs should not be allowed", User.isIdOrFullnameAllowed(""), is(false)); assertThat("Blank user IDs should not be allowed", User.isIdOrFullnameAllowed(" "), is(false)); } - + @Test @Issue("JENKINS-35967") public void shouldNotAllowIllegalRestrictedNamesInWrongCase() { @@ -53,7 +53,7 @@ public void shouldNotAllowIllegalRestrictedNamesInWrongCase() { assertIdOrFullNameNotAllowed("syStem"); assertIdOrFullNameNotAllowed("sYstEm"); } - + @Test @Issue("JENKINS-35967") public void shouldNotAllowIllegalRestrictedNamesEvenIfTrimmed() { @@ -62,13 +62,13 @@ public void shouldNotAllowIllegalRestrictedNamesEvenIfTrimmed() { assertIdOrFullNameNotAllowed(" " + username); assertIdOrFullNameNotAllowed(username + " "); assertIdOrFullNameNotAllowed(" " + username + " "); - assertIdOrFullNameNotAllowed("\t" + username + "\t"); + assertIdOrFullNameNotAllowed("\t" + username + "\t"); } } - + private void assertIdOrFullNameNotAllowed(String id) { - assertThat("User ID or full name '" + id + "' should not be allowed", + assertThat("User ID or full name '" + id + "' should not be allowed", User.isIdOrFullnameAllowed(id), is(false)); } - + } diff --git a/core/src/test/java/hudson/model/ViewTest.java b/core/src/test/java/hudson/model/ViewTest.java index dab90dbae3d9..e5374f133286 100644 --- a/core/src/test/java/hudson/model/ViewTest.java +++ b/core/src/test/java/hudson/model/ViewTest.java @@ -30,7 +30,7 @@ public void testAddDisplayNamesToSearchIndex() { final String displayName1 = "displayName1"; final String url2 = "url2"; final String displayName2 = "displayName2"; - + SearchIndexBuilder sib = new SearchIndexBuilder(); // mock the items to be indexed TopLevelItem item1 = Mockito.mock(TopLevelItem.class); @@ -42,7 +42,7 @@ public void testAddDisplayNamesToSearchIndex() { Collection items = new ArrayList<>(); items.add(item1); items.add(item2); - + // mock the view class except for the addDisplayNamesToSearchIndex() call as that // is what we are testing View view = Mockito.mock(View.class); @@ -51,9 +51,9 @@ public void testAddDisplayNamesToSearchIndex() { // now make the actual call to index items view.addDisplayNamesToSearchIndex(sib, items); - // make and index with sib + // make and index with sib SearchIndex index = sib.make(); - + // now make sure we can fetch item1 from the index List result = new ArrayList<>(); index.find(displayName1, result); @@ -87,9 +87,9 @@ public void getAllItems() { final TopLevelItem rootJob = createJob("rootJob"); final TopLevelItem sharedJob = createJob("sharedJob"); - + rootView = rootView.withJobs(rootJob, sharedJob); - + final TopLevelItem leftJob = createJob("leftJob"); final TopLevelItem rightJob = createJob("rightJob"); @@ -132,12 +132,12 @@ protected CompositeView(final String name, View... views) { super(name); this.views = views; } - + private CompositeView withJobs(TopLevelItem... jobs) { this.jobs = jobs; return this; } - + @Override public Collection getItems() { return Arrays.asList(this.jobs); @@ -147,7 +147,7 @@ public Collection getItems() { public Collection getViews() { return Arrays.asList(this.views); } - + @Override public boolean canDelete(View view) { return false; diff --git a/core/src/test/java/hudson/model/listeners/SCMListenerTest.java b/core/src/test/java/hudson/model/listeners/SCMListenerTest.java index ef201fc0a391..a85a4b7803c7 100644 --- a/core/src/test/java/hudson/model/listeners/SCMListenerTest.java +++ b/core/src/test/java/hudson/model/listeners/SCMListenerTest.java @@ -69,7 +69,7 @@ public class SCMListenerTest { l.onChangeLogParsed(r, scm, tl, cls); assertEquals("cannot handle this", 0, l.cnt); } - + private static class L extends SCMListener { int cnt; } diff --git a/core/src/test/java/hudson/scheduler/CronTabDayOfWeekLocaleTest.java b/core/src/test/java/hudson/scheduler/CronTabDayOfWeekLocaleTest.java index 1588f133685f..f9a287f2bc4c 100644 --- a/core/src/test/java/hudson/scheduler/CronTabDayOfWeekLocaleTest.java +++ b/core/src/test/java/hudson/scheduler/CronTabDayOfWeekLocaleTest.java @@ -36,13 +36,13 @@ public static Collection parameters() { } return parameters; } - + private final Locale locale; - + public CronTabDayOfWeekLocaleTest(Locale locale) { this.locale = locale; } - + /** * This unit test is an slight adaptation of the unit test found in * HUDSON-8656. @@ -53,220 +53,220 @@ public void hudson8656() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 23 * * 1-5"; // execute on weekdays @23:00 - + final CronTab cron = new CronTab(cronStr); final Calendar next = cron.ceil(cal); - + final Calendar expectedDate = Calendar.getInstance(); // Expected next: Monday, Jan 17th 2011, 23:00 expectedDate.set(2011, Calendar.JANUARY, 17, 23, 0, 0); compare(expectedDate, next); } - + @Test public void isSundayAndNextRunIsMonday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 0 * * 1"; // Mondays @00:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.ceil(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Monday, Jan 17th 2011, 00:00 expected.set(2011, Calendar.JANUARY, 17, 0, 0, 0); compare(expected, actual); } - + @Test public void isSundayAndPreviousRunIsMonday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 0 * * 1"; // Mondays @00:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.floor(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Monday, Jan 10th 2011, 00:00 expected.set(2011, Calendar.JANUARY, 10, 0, 0, 0); compare(expected, actual); } - + @Test public void isSundayAndNextRunIsTuesday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 0 * * 2"; // Tuesdays @00:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.ceil(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Tuesday, Jan 18th 2011, 00:00 expected.set(2011, Calendar.JANUARY, 18, 0, 0, 0); compare(expected, actual); } - + @Test public void isSundayAndPreviousRunIsTuesday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 0 * * 2"; // Tuesdays @00:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.floor(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Tuesday, Jan 11th 2011, 00:00 expected.set(2011, Calendar.JANUARY, 11, 0, 0, 0); compare(expected, actual); } - + @Test public void isSundayAndNextRunIsWednesday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 0 * * 3"; // Wednesdays @00:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.ceil(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Wednesday, Jan 19th 2011, 00:00 expected.set(2011, Calendar.JANUARY, 19, 0, 0, 0); compare(expected, actual); } - + @Test public void isSundayAndPreviousRunIsWednesday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 0 * * 3"; // Wednesdays @00:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.floor(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Wednesday, Jan 12th 2011, 00:00 expected.set(2011, Calendar.JANUARY, 12, 0, 0, 0); compare(expected, actual); } - + @Test public void isSundayAndNextRunIsThursday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 0 * * 4"; // Thursdays @00:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.ceil(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Thursday, Jan 20th 2011, 00:00 expected.set(2011, Calendar.JANUARY, 20, 0, 0, 0); compare(expected, actual); } - + @Test public void isSundayAndPreviousRunIsThursday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 0 * * 4"; // Thursdays @00:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.floor(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Thursday, Jan 13th 2011, 00:00 expected.set(2011, Calendar.JANUARY, 13, 0, 0, 0); compare(expected, actual); } - + @Test public void isSundayAndNextRunIsFriday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 0 * * 5"; // Fridays @00:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.ceil(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Friday, Jan 21th 2011, 00:00 expected.set(2011, Calendar.JANUARY, 21, 0, 0, 0); compare(expected, actual); } - + @Test public void isSundayAndPreviousRunIsFriday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 0 * * 5"; // Fridays @00:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.floor(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Friday, Jan 14th 2011, 00:00 expected.set(2011, Calendar.JANUARY, 14, 0, 0, 0); compare(expected, actual); } - + @Test public void isSundayAndNextRunIsSaturday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 0 * * 6"; // Saturdays @00:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.ceil(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Saturday, Jan 22th 2011, 00:00 expected.set(2011, Calendar.JANUARY, 22, 0, 0, 0); compare(expected, actual); } - + @Test public void isSundayAndPreviousRunIsSaturday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 0 * * 6"; // Saturdays @00:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.floor(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Saturday, Jan 15th 2011, 00:00 expected.set(2011, Calendar.JANUARY, 15, 0, 0, 0); compare(expected, actual); } - + @Test public void isSundayAndNextRunIsNextSunday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 1, 0, 0); // Sunday, Jan 16th 2011, 01:00 final String cronStr = "0 0 * * 0"; // Sundays @00:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.ceil(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Sunday, Jan 22th 2011, 00:00 expected.set(2011, Calendar.JANUARY, 23, 0, 0, 0); compare(expected, actual); } - + @Test public void isSundayAndPreviousRunIsPreviousSunday() throws Exception { final Calendar cal = Calendar.getInstance(locale); cal.set(2011, Calendar.JANUARY, 16, 0, 0, 0); // Sunday, Jan 16th 2011, 00:00 final String cronStr = "0 1 * * 0"; // Sundays @01:00 - + final CronTab cron = new CronTab(cronStr); final Calendar actual = cron.floor(cal); - + final Calendar expected = Calendar.getInstance(); // Expected next: Sunday, Jan 9th 2011, 01:00 expected.set(2011, Calendar.JANUARY, 9, 1, 0, 0); diff --git a/core/src/test/java/hudson/scheduler/CronTabEventualityTest.java b/core/src/test/java/hudson/scheduler/CronTabEventualityTest.java index 62cf37d7b624..333dd786784a 100644 --- a/core/src/test/java/hudson/scheduler/CronTabEventualityTest.java +++ b/core/src/test/java/hudson/scheduler/CronTabEventualityTest.java @@ -25,7 +25,7 @@ public static Collection parameters() { parameters.add(new Object[]{"seed2", Hash.from("seed2")}); return parameters; } - + private Calendar createLimit(Calendar start, int field, int amount){ Calendar limit = (Calendar)start.clone(); limit.add(field, amount); diff --git a/core/src/test/java/hudson/slaves/ComputerLauncherTest.java b/core/src/test/java/hudson/slaves/ComputerLauncherTest.java index 6b93ec643008..c019492d3484 100644 --- a/core/src/test/java/hudson/slaves/ComputerLauncherTest.java +++ b/core/src/test/java/hudson/slaves/ComputerLauncherTest.java @@ -139,7 +139,7 @@ public class ComputerLauncherTest { "OpenJDK Runtime Environment Zulu11.35+15-CA (build 11.0.5+10-LTS)\n" + "OpenJDK 64-Bit Server VM Zulu11.35+15-CA (build 11.0.5+10-LTS, mixed mode)", "11.0.5"); } - + private static void assertChecked(String text, String spec) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); ComputerLauncher.checkJavaVersion(new PrintStream(os), "bin/java", new BufferedReader(new StringReader(text))); diff --git a/core/src/test/java/hudson/tasks/_maven/Maven3MojoNoteTest.java b/core/src/test/java/hudson/tasks/_maven/Maven3MojoNoteTest.java index c063c813b53f..e67f1ea00491 100644 --- a/core/src/test/java/hudson/tasks/_maven/Maven3MojoNoteTest.java +++ b/core/src/test/java/hudson/tasks/_maven/Maven3MojoNoteTest.java @@ -8,26 +8,26 @@ public class Maven3MojoNoteTest { - @Test - public void testAnnotateMavenPlugin() { - check("[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ jobConfigHistory ---", "[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ jobConfigHistory ---"); - } - - @Test - public void testAnnotateCodehausPlugin() { - check("[INFO] --- cobertura-maven-plugin:2.4:instrument (report:cobertura) @ sardine ---", "[INFO] --- cobertura-maven-plugin:2.4:instrument (report:cobertura) @ sardine ---"); - - } - - @Test - public void testAnnotateOtherPlugin() { - check("[INFO] --- gmaven-plugin:1.0-rc-5:generateTestStubs (test-in-groovy) @ jobConfigHistory ---", "[INFO] --- gmaven-plugin:1.0-rc-5:generateTestStubs (test-in-groovy) @ jobConfigHistory ---"); - } - - private void check(final String decorated, final String input) { - assertTrue(input + " does not match" + Maven3MojoNote.PATTERN, Maven3MojoNote.PATTERN.matcher(input).matches()); - assertEquals(decorated, annotate(input)); - } + @Test + public void testAnnotateMavenPlugin() { + check("[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ jobConfigHistory ---", "[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ jobConfigHistory ---"); + } + + @Test + public void testAnnotateCodehausPlugin() { + check("[INFO] --- cobertura-maven-plugin:2.4:instrument (report:cobertura) @ sardine ---", "[INFO] --- cobertura-maven-plugin:2.4:instrument (report:cobertura) @ sardine ---"); + + } + + @Test + public void testAnnotateOtherPlugin() { + check("[INFO] --- gmaven-plugin:1.0-rc-5:generateTestStubs (test-in-groovy) @ jobConfigHistory ---", "[INFO] --- gmaven-plugin:1.0-rc-5:generateTestStubs (test-in-groovy) @ jobConfigHistory ---"); + } + + private void check(final String decorated, final String input) { + assertTrue(input + " does not match" + Maven3MojoNote.PATTERN, Maven3MojoNote.PATTERN.matcher(input).matches()); + assertEquals(decorated, annotate(input)); + } private String annotate(String text) { final MarkupText markupText = new MarkupText(text); diff --git a/core/src/test/java/hudson/util/ArgumentListBuilderTest.java b/core/src/test/java/hudson/util/ArgumentListBuilderTest.java index 09b9d207bc3e..858dc3c22d19 100644 --- a/core/src/test/java/hudson/util/ArgumentListBuilderTest.java +++ b/core/src/test/java/hudson/util/ArgumentListBuilderTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Yahoo! Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -119,15 +119,15 @@ public void testToWindowsCommand() { add("-Dfoo9=%'''%%@%"); // no quotes as none of the % are followed by a letter // By default, does not escape %VAR% assertThat(builder.toWindowsCommand().toCommandArray(), is(new String[] { "cmd.exe", "/C", - "\"ant.bat", "-Dfoo1=abc", "\"-Dfoo2=foo bar\"", "\"-Dfoo3=/u*r\"", "\"-Dfoo4=/us?\"", - "\"-Dfoo10=bar,baz\"", "\"-Dfoo5=foo;bar^baz\"", "\"-Dfoo6=&here;\"", - "\"-Dfoo7=foo|bar\"\"baz\"", "\"-Dfoo8=% %QED% %comspec% %-%(%.%\"", + "\"ant.bat", "-Dfoo1=abc", "\"-Dfoo2=foo bar\"", "\"-Dfoo3=/u*r\"", "\"-Dfoo4=/us?\"", + "\"-Dfoo10=bar,baz\"", "\"-Dfoo5=foo;bar^baz\"", "\"-Dfoo6=&here;\"", + "\"-Dfoo7=foo|bar\"\"baz\"", "\"-Dfoo8=% %QED% %comspec% %-%(%.%\"", "-Dfoo9=%'''%%@%", "&&", "exit", "%%ERRORLEVEL%%\"" })); // Pass flag to escape %VAR% assertThat(builder.toWindowsCommand(true).toCommandArray(), is(new String[] { "cmd.exe", "/C", - "\"ant.bat", "-Dfoo1=abc", "\"-Dfoo2=foo bar\"", "\"-Dfoo3=/u*r\"", "\"-Dfoo4=/us?\"", - "\"-Dfoo10=bar,baz\"", "\"-Dfoo5=foo;bar^baz\"", "\"-Dfoo6=&here;\"", - "\"-Dfoo7=foo|bar\"\"baz\"", "\"-Dfoo8=% %\"Q\"ED% %\"c\"omspec% %-%(%.%\"", + "\"ant.bat", "-Dfoo1=abc", "\"-Dfoo2=foo bar\"", "\"-Dfoo3=/u*r\"", "\"-Dfoo4=/us?\"", + "\"-Dfoo10=bar,baz\"", "\"-Dfoo5=foo;bar^baz\"", "\"-Dfoo6=&here;\"", + "\"-Dfoo7=foo|bar\"\"baz\"", "\"-Dfoo8=% %\"Q\"ED% %\"c\"omspec% %-%(%.%\"", "-Dfoo9=%'''%%@%", "&&", "exit", "%%ERRORLEVEL%%\"" })); // Try to hide password builder.add("-Dpassword=hidden", true); @@ -146,7 +146,7 @@ public void testToWindowsCommand() { + "\"\"-Dfoo8=% %\"Q\"ED% %\"c\"omspec% %-%(%.%\"\" -Dfoo9=%'''%%@% ****** " + "&& exit %%ERRORLEVEL%%\"")); } - + @Test @Ignore("It's only for reproduce JENKINS-28790 issue. It's added to testToWindowsCommand") @Issue("JENKINS-28790") @@ -189,7 +189,7 @@ public void assertMaskOnClone() { assertNotNull("The mask array should not be null", array); assertThat("The mask array was incorrect", array, is(builder.toMaskArray())); } - + private static final Map KEY_VALUES = new LinkedHashMap<>(); static { KEY_VALUES.put("key1", "value1"); @@ -198,7 +198,7 @@ public void assertMaskOnClone() { } private static final Set MASKS = Collections.singleton("key2"); - + @Test public void assertKeyValuePairsWithMask() { ArgumentListBuilder builder = new ArgumentListBuilder(); diff --git a/core/src/test/java/hudson/util/CopyOnWriteMapTest.java b/core/src/test/java/hudson/util/CopyOnWriteMapTest.java index f89de5af25b1..2b9de689d5bb 100644 --- a/core/src/test/java/hudson/util/CopyOnWriteMapTest.java +++ b/core/src/test/java/hudson/util/CopyOnWriteMapTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2010, Yahoo!, Inc., Alan Harder - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/test/java/hudson/util/DirScannerTest.java b/core/src/test/java/hudson/util/DirScannerTest.java index 4b702f77de58..6574bc42692b 100644 --- a/core/src/test/java/hudson/util/DirScannerTest.java +++ b/core/src/test/java/hudson/util/DirScannerTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2011, Christoph Thelen - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -46,22 +46,22 @@ public class DirScannerTest { FilePath git = tmp.child(".git"); git.mkdirs(); git.child("HEAD").touch(0); - + DirScanner glob1 = new DirScanner.Glob("**/*", null); DirScanner glob2 = new DirScanner.Glob("**/*", null, true); MatchingFileVisitor gitdir = new MatchingFileVisitor("HEAD"); MatchingFileVisitor gitignore = new MatchingFileVisitor(".gitignore"); - + glob1.scan(new File(tmp.getRemote()), gitdir); glob2.scan(new File(tmp.getRemote()), gitignore); - + assertFalse(gitdir.found); assertFalse(gitignore.found); } finally { tmp.deleteRecursive(); } } - + @Test public void globShouldIgnoreDefaultExcludesByRequest() throws Exception { FilePath tmp = new FilePath(tmpRule.getRoot()); try { @@ -69,31 +69,31 @@ public class DirScannerTest { FilePath git = tmp.child(".git"); git.mkdirs(); git.child("HEAD").touch(0); - + DirScanner glob = new DirScanner.Glob("**/*", null, false); MatchingFileVisitor gitdir = new MatchingFileVisitor("HEAD"); MatchingFileVisitor gitignore = new MatchingFileVisitor(".gitignore"); - + glob.scan(new File(tmp.getRemote()), gitdir); glob.scan(new File(tmp.getRemote()), gitignore); - + assertTrue(gitdir.found); assertTrue(gitignore.found); } finally { tmp.deleteRecursive(); } } - + private static class MatchingFileVisitor extends FileVisitor { - + public boolean found = false; - + public final String filename; - + MatchingFileVisitor(String filename) { this.filename = filename; } - + @Override public void visit(File f, String relativePath) { if (relativePath.endsWith(filename)) { diff --git a/core/src/test/java/hudson/util/Point.java b/core/src/test/java/hudson/util/Point.java index e349815653dc..b04f1ea105de 100644 --- a/core/src/test/java/hudson/util/Point.java +++ b/core/src/test/java/hudson/util/Point.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/test/java/hudson/util/ProcessTreeTest.java b/core/src/test/java/hudson/util/ProcessTreeTest.java index ef3f9c5b4555..d018f80b43b0 100644 --- a/core/src/test/java/hudson/util/ProcessTreeTest.java +++ b/core/src/test/java/hudson/util/ProcessTreeTest.java @@ -28,7 +28,7 @@ static class Tag implements Serializable { int id; private static final long serialVersionUID = 1L; } - + @Test public void remoting() throws Exception { Assume.assumeFalse("on some platforms where we fail to list any processes", ProcessTree.get()==ProcessTree.DEFAULT); diff --git a/core/src/test/java/hudson/util/RunListTest.java b/core/src/test/java/hudson/util/RunListTest.java index 5c61948b3113..53d08e1760af 100644 --- a/core/src/test/java/hudson/util/RunListTest.java +++ b/core/src/test/java/hudson/util/RunListTest.java @@ -37,53 +37,53 @@ */ public class RunListTest { - // RunList for byTimestamp tests - private RunList rlist; + // RunList for byTimestamp tests + private RunList rlist; - // RunList is ordered from most to least recent - private void setUpByTimestampRuns() { - Run r1 = mock(Run.class); - Run r2 = mock(Run.class); + // RunList is ordered from most to least recent + private void setUpByTimestampRuns() { + Run r1 = mock(Run.class); + Run r2 = mock(Run.class); - when(r1.getNumber()).thenReturn(1); - when(r2.getNumber()).thenReturn(2); + when(r1.getNumber()).thenReturn(1); + when(r2.getNumber()).thenReturn(2); - when(r1.getTimeInMillis()).thenReturn(200L); - when(r2.getTimeInMillis()).thenReturn(300L); + when(r1.getTimeInMillis()).thenReturn(200L); + when(r2.getTimeInMillis()).thenReturn(300L); - ArrayList list = new ArrayList<>(); - list.add(r2); - list.add(r1); + ArrayList list = new ArrayList<>(); + list.add(r2); + list.add(r1); - rlist = RunList.fromRuns(list); - } + rlist = RunList.fromRuns(list); + } - @Test - public void byTimestampAllRuns() { - setUpByTimestampRuns(); + @Test + public void byTimestampAllRuns() { + setUpByTimestampRuns(); - RunList tested = rlist.byTimestamp(0, 400); - assertEquals(2, tested.toArray().length); - } + RunList tested = rlist.byTimestamp(0, 400); + assertEquals(2, tested.toArray().length); + } @Issue("JENKINS-21159") - @Test - @SuppressWarnings("deprecation") - public void byTimestampFirstRun() { - setUpByTimestampRuns(); - // Only r1 - RunList tested = rlist.byTimestamp(150, 250); - assertEquals(1, tested.toArray().length); - assertEquals(1, tested.getFirstBuild().getNumber()); - } + @Test + @SuppressWarnings("deprecation") + public void byTimestampFirstRun() { + setUpByTimestampRuns(); + // Only r1 + RunList tested = rlist.byTimestamp(150, 250); + assertEquals(1, tested.toArray().length); + assertEquals(1, tested.getFirstBuild().getNumber()); + } - @Test - @SuppressWarnings("deprecation") - public void byTimestampLastRun() { - setUpByTimestampRuns(); - // Only r2 - RunList tested = rlist.byTimestamp(250, 350); - assertEquals(1, tested.toArray().length); - assertEquals(2, tested.getFirstBuild().getNumber()); - } + @Test + @SuppressWarnings("deprecation") + public void byTimestampLastRun() { + setUpByTimestampRuns(); + // Only r2 + RunList tested = rlist.byTimestamp(250, 350); + assertEquals(1, tested.toArray().length); + assertEquals(2, tested.getFirstBuild().getNumber()); + } } diff --git a/core/src/test/java/hudson/util/SecretTest.java b/core/src/test/java/hudson/util/SecretTest.java index 3806621e1693..316db2a7c5be 100644 --- a/core/src/test/java/hudson/util/SecretTest.java +++ b/core/src/test/java/hudson/util/SecretTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/test/java/hudson/util/io/TarArchiverTest.java b/core/src/test/java/hudson/util/io/TarArchiverTest.java index a5a34e28de81..401637028093 100644 --- a/core/src/test/java/hudson/util/io/TarArchiverTest.java +++ b/core/src/test/java/hudson/util/io/TarArchiverTest.java @@ -118,12 +118,12 @@ private static void run(FilePath dir, String... cmds) throws InterruptedExceptio Util.createSymlink(dir, "nonexistent", "link", TaskListener.NULL); new FilePath(dir).tar(new NullStream(), "**"); } - - + + /** * Test backing up an open file */ - + @Issue("JENKINS-20187") @Test public void growingFileTar() throws Exception { File file=new File(tmp.getRoot(),"growing.file"); @@ -132,7 +132,7 @@ private static void run(FilePath dir, String... cmds) throws InterruptedExceptio t1.start(); new FilePath(tmp.getRoot()).tar(new NullStream(), "**"); - + runnable1.doFinish(); t1.join(); } diff --git a/core/src/test/java/jenkins/model/CoreEnvironmentContributorTest.java b/core/src/test/java/jenkins/model/CoreEnvironmentContributorTest.java index 519a234f8fff..02ad4f0c809f 100644 --- a/core/src/test/java/jenkins/model/CoreEnvironmentContributorTest.java +++ b/core/src/test/java/jenkins/model/CoreEnvironmentContributorTest.java @@ -26,10 +26,10 @@ public class CoreEnvironmentContributorTest { @Mock Job job; - + @Mock TaskListener listener; - + @After public void tearDown() throws Exception { mocks.close(); diff --git a/core/src/test/java/jenkins/model/JDKNameTest.java b/core/src/test/java/jenkins/model/JDKNameTest.java index b9a5f0c3b4ab..941e5aa9670a 100644 --- a/core/src/test/java/jenkins/model/JDKNameTest.java +++ b/core/src/test/java/jenkins/model/JDKNameTest.java @@ -34,21 +34,21 @@ public class JDKNameTest { public void nullIsDefaultName() { assertThat(JDK.isDefaultName(null), is(true)); } - + @Test public void recognizeOldDefaultName() { // DEFAULT_NAME took this value prior to 1.598. assertThat(JDK.isDefaultName("(Default)"), is(true)); } - + @Test public void recognizeDefaultName() { assertThat(JDK.isDefaultName(JDK.DEFAULT_NAME), is(true)); } - + @Test public void othernameNotDefault() { assertThat(JDK.isDefaultName("I'm a customized name"), is(false)); } - + } diff --git a/core/src/test/java/jenkins/model/JenkinsGetRootUrlTest.java b/core/src/test/java/jenkins/model/JenkinsGetRootUrlTest.java index be5c82b82f23..8c5fc0510c7f 100644 --- a/core/src/test/java/jenkins/model/JenkinsGetRootUrlTest.java +++ b/core/src/test/java/jenkins/model/JenkinsGetRootUrlTest.java @@ -129,7 +129,7 @@ public void doNotInheritProtocolWhenDispatchingRequest2() { rootUrlIs("https://ci/jenkins/"); } } - + @Issue("JENKINS-10675") @Test public void useForwardedProtoWhenPresent() { @@ -203,7 +203,7 @@ public void useForwardedProtoWithIPv6WhenPresent() { } private void rootUrlFromRequestIs(final String expectedRootUrl) { - + assertThat(jenkins.getRootUrlFromRequest(), equalTo(expectedRootUrl)); } @@ -216,7 +216,7 @@ private void configured(final String configuredHost) { when(config.getUrl()).thenReturn(configuredHost); } - + private void withHeader(String name, final String value) { final StaplerRequest req = Stapler.getCurrentRequest(); when(req.getHeader(name)).thenReturn(value); diff --git a/core/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java b/core/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java index 30464bbdea79..f1b6fab3ef0b 100644 --- a/core/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java +++ b/core/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java @@ -37,29 +37,29 @@ * @author Oleg Nenashev */ public class JenkinsLocationConfigurationTest { - + JenkinsLocationConfiguration config; - + @Before public void setUp() { config = mock(JenkinsLocationConfiguration.class, Mockito.CALLS_REAL_METHODS); Answer mockVoid = invocation -> "stub"; - Mockito.doAnswer(mockVoid).when(config).save(); + Mockito.doAnswer(mockVoid).when(config).save(); Mockito.doAnswer(mockVoid).when(config).save(); } - + @Test public void setAdminEmail() { final String email="test@foo.bar"; final String email2="test@bar.foo"; - + // Assert the default value assertEquals(Messages.Mailer_Address_Not_Configured(), config.getAdminAddress()); - + // Basic case config.setAdminAddress(email); assertEquals(email, config.getAdminAddress()); - + // Quoted value config.setAdminAddress("\""+email2+"\""); assertEquals(email2, config.getAdminAddress()); @@ -67,16 +67,16 @@ public void setAdminEmail() { config.setAdminAddress(" test@foo.bar "); assertEquals(email,config.getAdminAddress()); } - + @Test @Issue("JENKINS-28419") public void resetAdminEmail() { final String email="test@foo.bar"; - + // Set the e-mail config.setAdminAddress(email); assertEquals(email, config.getAdminAddress()); - + // Reset it config.setAdminAddress(null); assertEquals(Messages.Mailer_Address_Not_Configured(), config.getAdminAddress()); diff --git a/core/src/test/java/jenkins/model/NewViewLinkTest.java b/core/src/test/java/jenkins/model/NewViewLinkTest.java index 8496da7cdbaa..c33baaf0c31c 100644 --- a/core/src/test/java/jenkins/model/NewViewLinkTest.java +++ b/core/src/test/java/jenkins/model/NewViewLinkTest.java @@ -17,7 +17,7 @@ import org.junit.Test; public class NewViewLinkTest { - + private NewViewLink newViewLink; private View view = mock(View.class); diff --git a/core/src/test/java/jenkins/model/labels/LabelAutoCompleteSeederTest.java b/core/src/test/java/jenkins/model/labels/LabelAutoCompleteSeederTest.java index 35f543c56756..3de02064165e 100644 --- a/core/src/test/java/jenkins/model/labels/LabelAutoCompleteSeederTest.java +++ b/core/src/test/java/jenkins/model/labels/LabelAutoCompleteSeederTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright 2010 Yahoo! Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/test/java/jenkins/model/lazy/AbstractLazyLoadRunMapTest.java b/core/src/test/java/jenkins/model/lazy/AbstractLazyLoadRunMapTest.java index 8f97ad8dbce7..c98a404e5dfe 100644 --- a/core/src/test/java/jenkins/model/lazy/AbstractLazyLoadRunMapTest.java +++ b/core/src/test/java/jenkins/model/lazy/AbstractLazyLoadRunMapTest.java @@ -81,7 +81,7 @@ protected BuildReference createReference(Build r) { }; } }; - + private final Map slowBuilderStartSemaphores = new HashMap<>(); private final Map slowBuilderEndSemaphores = new HashMap<>(); private final Map slowBuilderLoadCount = new HashMap<>(); @@ -105,7 +105,7 @@ protected Build retrieve(File dir) throws IOException { }; } }; - + @BeforeClass public static void setUpClass() { AbstractLazyLoadRunMap.LOGGER.setLevel(Level.OFF); diff --git a/core/src/test/java/jenkins/model/lazy/SortedListTest.java b/core/src/test/java/jenkins/model/lazy/SortedListTest.java index bc39bdf5d672..49aded8aba84 100644 --- a/core/src/test/java/jenkins/model/lazy/SortedListTest.java +++ b/core/src/test/java/jenkins/model/lazy/SortedListTest.java @@ -47,7 +47,7 @@ public void testCeil() { assertEquals(2,l.ceil("F")); assertEquals(3,l.ceil("G")); } - + @Test public void testFloor() { assertEquals(-1,l.floor("A")); diff --git a/core/src/test/java/jenkins/security/RedactSecretJsonInErrorMessageSanitizerTest.java b/core/src/test/java/jenkins/security/RedactSecretJsonInErrorMessageSanitizerTest.java index cef039cd38c3..54c63fdbc64e 100644 --- a/core/src/test/java/jenkins/security/RedactSecretJsonInErrorMessageSanitizerTest.java +++ b/core/src/test/java/jenkins/security/RedactSecretJsonInErrorMessageSanitizerTest.java @@ -39,7 +39,7 @@ public void noSecrets() { "{'a': 1, 'b': '2', 'c': {'c1': 1, 'c2': '2', 'c3': ['3a', '3b']}, 'd': ['4a', {'d1': 1, 'd2': '2'}]}" ); } - + @Test public void simpleWithSecret() { assertRedaction( @@ -47,7 +47,7 @@ public void simpleWithSecret() { "{'a': '[value redacted]', 'b': 'other', '$redact': 'a'}" ); } - + @Test public void singleWithRedactedInArray() { assertRedaction( @@ -55,7 +55,7 @@ public void singleWithRedactedInArray() { "{'a': '[value redacted]', 'b': 'other', '$redact': ['a']}" ); } - + @Test public void objectRedactedAcceptedButNotProcessed() { assertRedaction( @@ -63,7 +63,7 @@ public void objectRedactedAcceptedButNotProcessed() { "{'a': 'secret', 'b': 'other', '$redact': {'a': 'a'}}" ); } - + @Test public void weirdValuesInRedactedAcceptedButNotProcessed() { assertRedaction( @@ -71,7 +71,7 @@ public void weirdValuesInRedactedAcceptedButNotProcessed() { "{'a': '[value redacted]', 'b': 'other', '$redact': [null, true, false, 1, 2, 'a']}" ); } - + @Test public void ensureTrueAndOneAsStringAreSupportedAsRedactedKey() { //only null is not supported, as passing 'null' is considered as null @@ -80,7 +80,7 @@ public void ensureTrueAndOneAsStringAreSupportedAsRedactedKey() { "{'true': '[value redacted]', '1': '[value redacted]', 'b': 'other', '$redact': ['true', '1']}" ); } - + @Test public void redactFullBranch() { assertRedaction( @@ -88,7 +88,7 @@ public void redactFullBranch() { "{'a': '[value redacted]', 'b': '[value redacted]', 'c': 'other', '$redact': ['a', 'b']}" ); } - + @Test public void multipleSecretAtSameLevel() { assertRedaction( @@ -96,7 +96,7 @@ public void multipleSecretAtSameLevel() { "{'a1': '[value redacted]', 'a2': '[value redacted]', 'b': 'other', '$redact': ['a1', 'a2']}" ); } - + @Test public void redactedKeyWithoutCorrespondences() { assertRedaction( @@ -104,7 +104,7 @@ public void redactedKeyWithoutCorrespondences() { "{'a1': '[value redacted]', 'a2': '[value redacted]', 'b': 'other', '$redact': ['a0', 'a1', 'a2', 'a3']}" ); } - + @Test public void secretsAtMultipleLevels() { assertRedaction( @@ -112,7 +112,7 @@ public void secretsAtMultipleLevels() { "{'a1': '[value redacted]', 'a2': '[value redacted]', 'b': 'other', '$redact': ['a1', 'a2'], 'sub': {'c1': '[value redacted]', 'c2': '[value redacted]', 'c3': 'other', '$redact': ['c1', 'c2']}}" ); } - + @Test public void noInteractionBetweenLevels() { assertRedaction( @@ -120,7 +120,7 @@ public void noInteractionBetweenLevels() { "{'a': '[value redacted]', 'b': 'other', 'c': 'other', '$redact': 'a', 'sub': {'a': 'other', 'b': '[value redacted]', 'c': 'other', '$redact': 'b'}}" ); } - + @Test public void deeplyNestedObject() { assertRedaction( @@ -128,7 +128,7 @@ public void deeplyNestedObject() { "{'sub': {'arr': ['d1', 2, {'a1': 'other', 'b1':'other', 'c1': '[value redacted]', '$redact': 'c1'}, 4, {'a2': 'other', 'b2': 'other', 'c2': '[value redacted]', '$redact': 'c2'}]}, '$redact': 'b'}" ); } - + private void assertRedaction(String from, String to) { JSONObject input = JSONObject.fromObject(from.replace('\'', '"')); JSONObject output = RedactSecretJsonInErrorMessageSanitizer.INSTANCE.sanitize(input); diff --git a/core/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java b/core/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java index eb2407f1138c..741f407b1e98 100644 --- a/core/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java +++ b/core/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java @@ -61,14 +61,14 @@ public class ApiTokenStatsTest { @Rule public TemporaryFolder tmp = new TemporaryFolder(); - + @Before public void prepareConfig() { // to separate completely the class under test from its environment ApiTokenPropertyConfiguration mockConfig = Mockito.mock(ApiTokenPropertyConfiguration.class); } - + @Test public void regularUsage() throws Exception { final String ID_1 = UUID.randomUUID().toString(); @@ -164,7 +164,7 @@ public void regularUsage() throws Exception { } } } - + @Test public void testResilientIfFileDoesNotExist() { ApiTokenPropertyConfiguration mockConfig = mock(ApiTokenPropertyConfiguration.class); @@ -175,7 +175,7 @@ public void testResilientIfFileDoesNotExist() { assertNotNull(tokenStats); } } - + @Test public void resistantToDuplicatedUuid() throws Exception { final String ID_1 = UUID.randomUUID().toString(); @@ -224,7 +224,7 @@ public void resistantToDuplicatedUuid() throws Exception { } } } - + @Test public void resistantToDuplicatedUuid_withNull() throws Exception { final String ID = "ID"; @@ -257,7 +257,7 @@ public void resistantToDuplicatedUuid_withNull() throws Exception { } } } - + @Test @SuppressWarnings("unchecked") public void testInternalComparator() throws Exception { @@ -288,14 +288,14 @@ public void testInternalComparator() throws Exception { assertThat(idList, contains("A", "B", "C", "D")); } } - + private ApiTokenStats.SingleTokenStats createSingleTokenStatsByReflection(String uuid, String dateString, Integer counter) throws Exception { Class clazz = ApiTokenStats.SingleTokenStats.class; Constructor constructor = clazz.getDeclaredConstructor(String.class); constructor.setAccessible(true); - + ApiTokenStats.SingleTokenStats result = constructor.newInstance(uuid); - + { Field field = clazz.getDeclaredField("useCounter"); field.setAccessible(true); @@ -306,10 +306,10 @@ private ApiTokenStats.SingleTokenStats createSingleTokenStatsByReflection(String field.setAccessible(true); field.set(result, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(dateString)); } - + return result; } - + @Test public void testDayDifference() throws Exception { final String ID = UUID.randomUUID().toString(); @@ -335,14 +335,14 @@ public void testDayDifference() throws Exception { assertThat(stats.getNumDaysUse(), greaterThanOrEqualTo(2L)); } } - + private ApiTokenStats createFromFile(File file){ ApiTokenStats result = ApiTokenStats.internalLoad(file); if (result == null) { result = new ApiTokenStats(); result.parent = file; } - + return result; } } diff --git a/core/src/test/java/jenkins/util/TreeStringBuilderTest.java b/core/src/test/java/jenkins/util/TreeStringBuilderTest.java index 3545a1054d53..e543657eb69c 100644 --- a/core/src/test/java/jenkins/util/TreeStringBuilderTest.java +++ b/core/src/test/java/jenkins/util/TreeStringBuilderTest.java @@ -12,8 +12,6 @@ * * @author Kohsuke Kawaguchi */ -@SuppressWarnings({"PMD", "all"}) -//CHECKSTYLE:OFF public class TreeStringBuilderTest { /** * Tests the simple operations inside the builder. diff --git a/core/src/test/java/jenkins/util/UrlHelperTest.java b/core/src/test/java/jenkins/util/UrlHelperTest.java index 2e0d54b40e67..2177e7c671bd 100644 --- a/core/src/test/java/jenkins/util/UrlHelperTest.java +++ b/core/src/test/java/jenkins/util/UrlHelperTest.java @@ -52,21 +52,21 @@ public void regularCases() { assertFalse(UrlHelper.isValidRootUrl("http://::::@example.com")); assertFalse(UrlHelper.isValidRootUrl("ftp://jenkins")); } - + @Test public void fragmentIsForbidden(){ // this url will be used as a root url and so will be concatenated with other part, fragment part is not allowed assertFalse(UrlHelper.isValidRootUrl("http://jenkins#fragment")); assertFalse(UrlHelper.isValidRootUrl("http://jenkins.com#fragment")); } - + @Test public void queryIsForbidden(){ // this url will be used as a root url and so will be concatenated with other part, query part is not allowed assertFalse(UrlHelper.isValidRootUrl("http://jenkins?param=test")); assertFalse(UrlHelper.isValidRootUrl("http://jenkins.com?param=test")); } - + @Test public void otherCharactersAreForbidden(){ // other characters are not allowed @@ -80,7 +80,7 @@ public void otherCharactersAreForbidden(){ assertFalse(UrlHelper.isValidRootUrl("http://jenk!ins.com")); assertFalse(UrlHelper.isValidRootUrl("http://jenk?ins.com")); } - + @Test public void ipv4Allowed(){ assertTrue(UrlHelper.isValidRootUrl("http://172.52.125.12")); @@ -88,7 +88,7 @@ public void ipv4Allowed(){ assertTrue(UrlHelper.isValidRootUrl("http://172.52.125.12:8080")); assertTrue(UrlHelper.isValidRootUrl("http://172.52.125.12:8080/jenkins")); } - + @Test public void ipv6Allowed() { assertTrue(UrlHelper.isValidRootUrl("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]")); @@ -99,7 +99,7 @@ public void ipv6Allowed() { assertTrue(UrlHelper.isValidRootUrl("http://[FEDC::3210:FEDC:BA98:7654:3210]")); // but only one sequence assertFalse(UrlHelper.isValidRootUrl("http://[2001::85a3::ac1f]")); - + // port and path are still allowed assertTrue(UrlHelper.isValidRootUrl("http://[FEDC:0:0:3210:FEDC:BA98:7654:3210]:8001/jenkins")); assertTrue(UrlHelper.isValidRootUrl("http://[FEDC:0:0:3210:FEDC:BA98:7654:3210]:8001")); @@ -108,7 +108,7 @@ public void ipv6Allowed() { assertFalse(UrlHelper.isValidRootUrl("http://[FEDC:0:0:32-10:FEDC:BA98:7654:3210]:8001/jenkins")); assertFalse(UrlHelper.isValidRootUrl("http://[FEDC:0:0:3210:-FEDC:BA98:7654:3210]:8001/jenkins")); } - + @Test @Issue("JENKINS-51064") public void withCustomDomain() { @@ -118,16 +118,16 @@ public void withCustomDomain() { assertTrue(UrlHelper.isValidRootUrl("http://my-server.domain:8080/jenkins")); assertTrue(UrlHelper.isValidRootUrl("http://my-ser_ver.do_m-ain:8080/jenkins")); assertTrue(UrlHelper.isValidRootUrl("http://my-ser_ver.do_m-ain:8080/jenkins")); - + // forbidden to start or end domain with - or . assertFalse(UrlHelper.isValidRootUrl("http://-jenkins.com")); assertFalse(UrlHelper.isValidRootUrl("http://jenkins.com-")); assertFalse(UrlHelper.isValidRootUrl("http://.jenkins.com")); - + // allowed to have multiple dots in chain assertTrue(UrlHelper.isValidRootUrl("http://jen..kins.com")); } - + @Test public void multipleConsecutiveDashesAreAllowed() { assertTrue(UrlHelper.isValidRootUrl("http://jenk--ins.internal/")); @@ -135,7 +135,7 @@ public void multipleConsecutiveDashesAreAllowed() { // even with subdomain being just a dash assertTrue(UrlHelper.isValidRootUrl("http://www.go.-.--.--ogle.com/")); } - + @Test @Issue("JENKINS-51158") public void trailingDotsAreAccepted() { diff --git a/core/src/test/java/jenkins/util/VirtualFileTest.java b/core/src/test/java/jenkins/util/VirtualFileTest.java index ab2be7f8f1ea..3a091a5272ec 100644 --- a/core/src/test/java/jenkins/util/VirtualFileTest.java +++ b/core/src/test/java/jenkins/util/VirtualFileTest.java @@ -81,7 +81,7 @@ public class VirtualFileTest { @Rule public TemporaryFolder tmp = new TemporaryFolder(); - + @Issue("SECURITY-162") @Test public void outsideSymlinks() throws Exception { assumeFalse(Functions.isWindows()); diff --git a/core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java b/core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java index 58ecec686ccf..2f7b64e6fa5e 100644 --- a/core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java +++ b/core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java @@ -144,17 +144,17 @@ public void testDomInMap() { assertThat(v2, instanceOf(DomInMap.class)); assertXStreamDOMEquals(v.values.get("foo"), ((DomInMap)v2).values.get("foo")); } - + private void assertXStreamDOMEquals(XStreamDOM expected, XStreamDOM actual) { assertEquals(expected.getTagName(), actual.getTagName()); assertEquals(expected.getValue(), actual.getValue()); - + assertEquals(expected.getAttributeCount(), actual.getAttributeCount()); for (int i=0; i\n" + @@ -126,5 +126,5 @@ public void testParse_with_XXE() { StringReader stringReader = new StringReader(xml); final SAXException e = assertThrows(SAXException.class, () -> XMLUtils.parse(stringReader)); assertThat(e.getMessage(), containsString("\"http://apache.org/xml/features/disallow-doctype-decl\"")); - } + } } diff --git a/core/src/test/java/org/acegisecurity/util/FieldUtilsTest.java b/core/src/test/java/org/acegisecurity/util/FieldUtilsTest.java index 1b251ee5c92e..db0d314783ff 100644 --- a/core/src/test/java/org/acegisecurity/util/FieldUtilsTest.java +++ b/core/src/test/java/org/acegisecurity/util/FieldUtilsTest.java @@ -45,7 +45,7 @@ class InnerClassWithPublicFinalField { public String getMyField() { return myField; } - + } public class InnerClassWithProtectedField { diff --git a/pom.xml b/pom.xml index 7904b13ebdc0..33853e1a3363 100644 --- a/pom.xml +++ b/pom.xml @@ -60,8 +60,8 @@ THE SOFTWARE. scm:git:git://github.com/jenkinsci/jenkins.git scm:git:ssh://git@github.com/jenkinsci/jenkins.git - https://github.com/jenkinsci/jenkins ${scmTag} + https://github.com/jenkinsci/jenkins @@ -105,24 +105,6 @@ THE SOFTWARE. 2.18.0 - - - - repo.jenkins-ci.org - https://repo.jenkins-ci.org/public/ - - - - - - - repo.jenkins-ci.org - https://repo.jenkins-ci.org/public/ - - - @@ -156,16 +138,36 @@ THE SOFTWARE. + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + install - ${basedir}/src/main/resources false + ${basedir}/src/main/resources - ${basedir}/src/filter/resources true + ${basedir}/src/filter/resources @@ -236,7 +238,8 @@ THE SOFTWARE. 3600 true - false + + false alphabetical @@ -392,13 +395,6 @@ THE SOFTWARE. org.apache.maven.plugins maven-checkstyle-plugin - - - com.puppycrawl.tools - checkstyle - 9.2.1 - - true @@ -493,13 +489,20 @@ THE SOFTWARE. + + + com.puppycrawl.tools + checkstyle + 9.2.1 + + validate - validate check + validate @@ -511,8 +514,20 @@ THE SOFTWARE. + + true + + + + + ${project.build.sourceEncoding} + \n + false + true + + @@ -561,13 +576,6 @@ THE SOFTWARE. org.codehaus.mojo animal-sniffer-maven-plugin - - - - check - - - org.codehaus.mojo.signature @@ -575,6 +583,13 @@ THE SOFTWARE. 1.0 + + + + check + + + @@ -685,10 +700,10 @@ THE SOFTWARE. sign-artifacts - verify sign + verify @@ -703,14 +718,14 @@ THE SOFTWARE. m2e - - target - m2e.version + + target + ${m2BuildDirectory} @@ -745,6 +760,9 @@ THE SOFTWARE. jdk11 + + 11 + none @@ -756,9 +774,6 @@ THE SOFTWARE. once we drop support for JDK 8 that only recognize source and target. --> ${java.level} - - 11 - diff --git a/src/spotbugs/spotbugs-excludes.xml b/src/spotbugs/spotbugs-excludes.xml index b08e519512f3..17ee189827ef 100644 --- a/src/spotbugs/spotbugs-excludes.xml +++ b/src/spotbugs/spotbugs-excludes.xml @@ -83,12 +83,235 @@ - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -133,10 +356,6 @@ - - - - @@ -150,10 +369,6 @@ - - - - @@ -220,10 +435,6 @@ - - - - diff --git a/test/pom.xml b/test/pom.xml index 6729dcb63072..5d949a610cd6 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -37,9 +37,11 @@ THE SOFTWARE. Functional tests for Jenkins core - 2 + + 2 false - + + @@ -196,11 +198,11 @@ THE SOFTWARE. old-remoting-for-test - generate-test-resources copy + generate-test-resources @@ -314,10 +316,10 @@ THE SOFTWARE. --> post-unit-test - test report + test ${project.build.directory}/coverage-reports/jacoco-ut.exec diff --git a/test/src/test/java/hudson/AboutJenkinsTest.java b/test/src/test/java/hudson/AboutJenkinsTest.java index 0229b5b9d8fc..4eb9b5db4105 100644 --- a/test/src/test/java/hudson/AboutJenkinsTest.java +++ b/test/src/test/java/hudson/AboutJenkinsTest.java @@ -40,10 +40,10 @@ @Category(SmokeTest.class) public class AboutJenkinsTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Test @Issue("SECURITY-771") public void onlyAdminOrManageOrSystemReadCanReadAbout() throws Exception { @@ -52,7 +52,7 @@ public void onlyAdminOrManageOrSystemReadCanReadAbout() throws Exception { final String MANAGER = "manager"; final String READONLY = "readonly"; final String MANAGER_READONLY = "manager-readonly"; - + j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() // full access @@ -74,16 +74,16 @@ public void onlyAdminOrManageOrSystemReadCanReadAbout() throws Exception { .grant(Jenkins.MANAGE).everywhere().to(MANAGER_READONLY) .grant(Jenkins.SYSTEM_READ).everywhere().to(MANAGER_READONLY) ); - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); - + { // user cannot see it wc.login(USER); HtmlPage page = wc.goTo("about/"); assertEquals(HttpURLConnection.HTTP_FORBIDDEN, page.getWebResponse().getStatusCode()); } - + { // admin can access it wc.login(ADMIN); HtmlPage page = wc.goTo("about/"); @@ -109,5 +109,5 @@ public void onlyAdminOrManageOrSystemReadCanReadAbout() throws Exception { assertEquals(HttpURLConnection.HTTP_OK, page.getWebResponse().getStatusCode()); } } - + } diff --git a/test/src/test/java/hudson/ClassicPluginStrategyTest.java b/test/src/test/java/hudson/ClassicPluginStrategyTest.java index c046d12e66ee..8038e697cddc 100644 --- a/test/src/test/java/hudson/ClassicPluginStrategyTest.java +++ b/test/src/test/java/hudson/ClassicPluginStrategyTest.java @@ -55,7 +55,7 @@ public class ClassicPluginStrategyTest { @Override protected Hudson newHudson() throws Exception { File home = homeLoader.allocate(); - + for (JenkinsRecipe.Runner r : recipes) { r.decorateHome(this,home); } diff --git a/test/src/test/java/hudson/CustomPluginManagerTest.java b/test/src/test/java/hudson/CustomPluginManagerTest.java index 0b702dcc73a5..bd7a20aada54 100644 --- a/test/src/test/java/hudson/CustomPluginManagerTest.java +++ b/test/src/test/java/hudson/CustomPluginManagerTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2016 CloudBees, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/test/src/test/java/hudson/ExtensionFinderTest.java b/test/src/test/java/hudson/ExtensionFinderTest.java index 4eb61bae16de..53b4e0829bca 100644 --- a/test/src/test/java/hudson/ExtensionFinderTest.java +++ b/test/src/test/java/hudson/ExtensionFinderTest.java @@ -133,7 +133,7 @@ public void errorRecovery() { public static class BrokenExtension extends PageDecorator { public BrokenExtension() { super(InjectingExtension.class); - + throw new Error(); } } diff --git a/test/src/test/java/hudson/FilePathTest.java b/test/src/test/java/hudson/FilePathTest.java index f5f4eb8adee8..48786eee7610 100644 --- a/test/src/test/java/hudson/FilePathTest.java +++ b/test/src/test/java/hudson/FilePathTest.java @@ -97,11 +97,11 @@ public void zipAbsolutePathHandledCorrectly_win() throws Exception { FilePath zipFile = r.jenkins.getRootPath().child("zip-slip-win.zip"); FilePath targetLocation = r.jenkins.getRootPath().child("unzip-target"); - + FilePath good = targetLocation.child("good.txt"); assertThat(good.exists(), is(false)); - + IOException e = assertThrows(IOException.class, () -> zipFile.unzip(targetLocation)); assertThat(e.getMessage(), containsString("contains illegal file name that breaks out of the target directory")); @@ -155,7 +155,7 @@ public void zipRelativePathHandledCorrectly_oneUp() throws Exception { assertThat(simple3.exists(), is(false)); } - + @Test @Issue("XXX") @LocalData("zip_with_relative") diff --git a/test/src/test/java/hudson/LauncherTest.java b/test/src/test/java/hudson/LauncherTest.java index 3833b07d2168..4cfbfd11e21c 100644 --- a/test/src/test/java/hudson/LauncherTest.java +++ b/test/src/test/java/hudson/LauncherTest.java @@ -91,14 +91,14 @@ public void correctlyExpandEnvVars() throws Exception { rule.assertLogContains("aaa aaaccc ccc", build); } - + @Issue("JENKINS-19926") @Test public void overwriteSystemEnvVars() throws Exception { Map env = new HashMap<>(); env.put("jenkins_19926", "original value"); Slave slave = rule.createSlave(new EnvVars(env)); - + FreeStyleProject project = rule.createFreeStyleProject(); project.addProperty(new ParametersDefinitionProperty(new StringParameterDefinition("jenkins_19926", "${jenkins_19926} and new value"))); final CommandInterpreter script = Functions.isWindows() diff --git a/test/src/test/java/hudson/PluginManagerTest.java b/test/src/test/java/hudson/PluginManagerTest.java index adc30e6aa6cc..06e4722b0bbe 100644 --- a/test/src/test/java/hudson/PluginManagerTest.java +++ b/test/src/test/java/hudson/PluginManagerTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -148,7 +148,7 @@ public void doDynamic(StaplerRequest staplerRequest, StaplerResponse staplerResp staplerResponse.serveFile(staplerRequest, PluginManagerTest.class.getClassLoader().getResource("plugins/htmlpublisher.jpi")); } } - + /** * Tests the effect of {@link WithPlugin}. */ @@ -156,7 +156,7 @@ public void doDynamic(StaplerRequest staplerRequest, StaplerResponse staplerResp @Test public void withRecipeJpi() { assertNotNull(r.jenkins.getPlugin("htmlpublisher")); } - + /** * Tests the effect of {@link WithPlugin}. */ @@ -265,10 +265,10 @@ public void startPlugin(PluginWrapper plugin) throws Exception { // return "dependee"; // } // } - // + // // public abstract class DependeeExtensionPoint implements ExtensionPoint { // } - // + // // org.jenkinsci.plugins.dependencytest.depender: // public class Depender { // public static String getValue() { @@ -278,12 +278,12 @@ public void startPlugin(PluginWrapper plugin) throws Exception { // return "depender"; // } // } - // + // // @Extension(optional=true) // public class DependerExtension extends DependeeExtensionPoint { // } - - + + /** * call org.jenkinsci.plugins.dependencytest.depender.Depender.getValue(). */ @@ -292,7 +292,7 @@ private String callDependerValue() throws Exception { Method m = c.getMethod("getValue"); return (String)m.invoke(null); } - + /** * Load "dependee" and then load "depender". * Asserts that "depender" can access to "dependee". @@ -302,25 +302,25 @@ private String callDependerValue() throws Exception { { dynamicLoad("dependee.hpi"); } - + // before load depender, of course failed to call Depender.getValue() assertThrows(ClassNotFoundException.class, this::callDependerValue); - + // No extensions exist. assertTrue(r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint").isEmpty()); - + // Load depender. { dynamicLoad("depender.hpi"); } - + // depender successfully accesses to dependee. assertEquals("dependee", callDependerValue()); - + // Extension in depender is loaded. assertFalse(r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint").isEmpty()); } - + /** * Load "depender" and then load "dependee". * Asserts that "depender" can access to "dependee". @@ -331,10 +331,10 @@ private String callDependerValue() throws Exception { { dynamicLoad("depender.hpi"); } - + // before load dependee, depender does not access to dependee. assertEquals("depender", callDependerValue()); - + // before load dependee, of course failed to list extensions for dependee. assertThrows(ClassNotFoundException.class, () -> r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint")); // Extension extending a dependee class can't be loaded either @@ -344,7 +344,7 @@ private String callDependerValue() throws Exception { { dynamicLoad("dependee.hpi"); } - + // (MUST) Not throws an exception // (SHOULD) depender successfully accesses to dependee. assertEquals("dependee", callDependerValue()); @@ -525,17 +525,17 @@ private void dynamicLoadAndDisable(String plugin) throws IOException, Interrupte // wait for all the download jobs to complete boolean done = true; - boolean passed = true; + boolean passed = true; do { Thread.sleep(100); - done = true; - for(UpdateCenterJob job : r.jenkins.getUpdateCenter().getJobs()) { + done = true; + for(UpdateCenterJob job : r.jenkins.getUpdateCenter().getJobs()) { if(job instanceof UpdateCenter.DownloadJob) { - UpdateCenter.DownloadJob j = (UpdateCenter.DownloadJob)job; - assertFalse(j.status instanceof UpdateCenter.DownloadJob.Failure); + UpdateCenter.DownloadJob j = (UpdateCenter.DownloadJob)job; + assertFalse(j.status instanceof UpdateCenter.DownloadJob.Failure); done &= !(j.status instanceof UpdateCenter.DownloadJob.Pending || - j.status instanceof UpdateCenter.DownloadJob.Installing); - } + j.status instanceof UpdateCenter.DownloadJob.Installing); + } } } while(!done); diff --git a/test/src/test/java/hudson/bugs/JnlpAccessWithSecuredHudsonTest.java b/test/src/test/java/hudson/bugs/JnlpAccessWithSecuredHudsonTest.java index 9ca40255bb5f..ba9896d3bdba 100644 --- a/test/src/test/java/hudson/bugs/JnlpAccessWithSecuredHudsonTest.java +++ b/test/src/test/java/hudson/bugs/JnlpAccessWithSecuredHudsonTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -60,7 +60,7 @@ import org.jvnet.hudson.test.recipes.PresetData.DataSet; /** - * Makes sure that the jars that web start needs are readable, even when the anonymous user doesn't have any read access. + * Makes sure that the jars that web start needs are readable, even when the anonymous user doesn't have any read access. * * @author Kohsuke Kawaguchi */ @@ -84,7 +84,7 @@ protected Slave createNewJnlpSlave(String name) throws Exception { @Test public void anonymousCanAlwaysLoadJARs() throws Exception { ApiTokenTestHelper.enableLegacyBehavior(); - + r.jenkins.setNodes(Collections.singletonList(createNewJnlpSlave("test"))); JenkinsRule.WebClient wc = r.createWebClient(); HtmlPage p = wc.withBasicApiToken(User.getById("alice", true)).goTo("computer/test/"); @@ -99,7 +99,7 @@ public void anonymousCanAlwaysLoadJARs() throws Exception { for( Object jar : dom.selectNodes("//jar") ) { URL url = new URL(baseUrl,((Element)jar).attributeValue("href")); System.out.println(url); - + // now make sure that these URLs are unprotected Page jarResource = jnlpAgent.getPage(url); assertTrue(jarResource.getWebResponse().getContentType().toLowerCase(Locale.ENGLISH).startsWith("application/")); diff --git a/test/src/test/java/hudson/bugs/seasar/package-info.java b/test/src/test/java/hudson/bugs/seasar/package-info.java index 7754314705e1..b6bea7282b59 100644 --- a/test/src/test/java/hudson/bugs/seasar/package-info.java +++ b/test/src/test/java/hudson/bugs/seasar/package-info.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/test/src/test/java/hudson/cli/BuildCommandTest.java b/test/src/test/java/hudson/cli/BuildCommandTest.java index c187a5205a84..6d075a9e3aa4 100644 --- a/test/src/test/java/hudson/cli/BuildCommandTest.java +++ b/test/src/test/java/hudson/cli/BuildCommandTest.java @@ -226,7 +226,7 @@ public void executorsAliveOnParameterWithNullDefaultValue() throws Exception { FreeStyleProject project = j.createFreeStyleProject("foo"); project.setAssignedNode(slave); - // Create test parameter with Null default value + // Create test parameter with Null default value NullDefaultValueParameterDefinition nullDefaultDefinition = new NullDefaultValueParameterDefinition(); ParametersDefinitionProperty pdp = new ParametersDefinitionProperty( new StringParameterDefinition("string", "defaultValue", "description"), diff --git a/test/src/test/java/hudson/cli/CLIActionTest.java b/test/src/test/java/hudson/cli/CLIActionTest.java index 69ed23a7e598..457ecaf554cc 100644 --- a/test/src/test/java/hudson/cli/CLIActionTest.java +++ b/test/src/test/java/hudson/cli/CLIActionTest.java @@ -78,7 +78,7 @@ public void serveCliActionToAnonymousUserWithAnonymousUserWithPermissions() thro @Test public void authentication() throws Exception { ApiTokenTestHelper.enableLegacyBehavior(); - + logging.record(PlainCLIProtocol.class, Level.FINE); File jar = tmp.newFile("jenkins-cli.jar"); FileUtils.copyURLToFile(j.jenkins.getJnlpJars("jenkins-cli.jar").getURL(), jar); diff --git a/test/src/test/java/hudson/cli/CLITest.java b/test/src/test/java/hudson/cli/CLITest.java index 0cfecbda0d19..ae308b118efb 100644 --- a/test/src/test/java/hudson/cli/CLITest.java +++ b/test/src/test/java/hudson/cli/CLITest.java @@ -74,7 +74,7 @@ public class CLITest { @ClassRule public static BuildWatcher buildWatcher = new BuildWatcher(); - + @Rule public JenkinsRule r = new JenkinsRule(); @@ -170,7 +170,7 @@ public void redirectToEndpointShouldBeFollowed() throws Exception { JenkinsRule.WebClient wc = r.createWebClient() .withRedirectEnabled(false) .withThrowExceptionOnFailingStatusCode(false); - + WebResponse rsp = wc.goTo("cli-proxy/").getWebResponse(); assertEquals(rsp.getContentAsString(), HttpURLConnection.HTTP_MOVED_TEMP, rsp.getStatusCode()); assertNull(rsp.getContentAsString(), rsp.getResponseHeaderValue("X-Jenkins")); diff --git a/test/src/test/java/hudson/cli/ConsoleCommandTest.java b/test/src/test/java/hudson/cli/ConsoleCommandTest.java index e3a232b4ad4b..a23a678a119f 100644 --- a/test/src/test/java/hudson/cli/ConsoleCommandTest.java +++ b/test/src/test/java/hudson/cli/ConsoleCommandTest.java @@ -75,23 +75,23 @@ public class ConsoleCommandTest { assertThat(result, hasNoStandardOutput()); assertThat(result.stderr(), containsString("ERROR: No such job 'aProject'")); } - + @Issue("JENKINS-52181") - @Test public void consoleShouldBeAccessibleForUserWithRead() throws Exception { - FreeStyleProject project = j.createFreeStyleProject("aProject"); + @Test public void consoleShouldBeAccessibleForUserWithRead() throws Exception { + FreeStyleProject project = j.createFreeStyleProject("aProject"); if (Functions.isWindows()) { project.getBuildersList().add(new BatchFile("echo 1")); } else { project.getBuildersList().add(new Shell("echo 1")); } j.assertLogContains("echo 1", j.buildAndAssertSuccess(project)); - - final CLICommandInvoker.Result result = command - .authorizedTo(Jenkins.READ, Item.READ) - .invokeWithArgs("aProject"); - + + final CLICommandInvoker.Result result = command + .authorizedTo(Jenkins.READ, Item.READ) + .invokeWithArgs("aProject"); + assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("echo 1")); + assertThat(result.stdout(), containsString("echo 1")); } @Test public void consoleShouldFailWhenProjectDoesNotExist() { diff --git a/test/src/test/java/hudson/cli/ListPluginsCommandTest.java b/test/src/test/java/hudson/cli/ListPluginsCommandTest.java index 7bd7e2df7d2b..4cd2ee0a08d4 100644 --- a/test/src/test/java/hudson/cli/ListPluginsCommandTest.java +++ b/test/src/test/java/hudson/cli/ListPluginsCommandTest.java @@ -36,10 +36,10 @@ import org.jvnet.hudson.test.JenkinsRule; public class ListPluginsCommandTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Test public void listPluginsExpectedUsage() { assertNull(j.jenkins.getPluginManager().getPlugin("token-macro")); @@ -48,20 +48,20 @@ public void listPluginsExpectedUsage() { assertThat(result, CLICommandInvoker.Matcher.succeeded()); assertThat(result, CLICommandInvoker.Matcher.hasNoStandardOutput()); assertThat(result.stdout(), not(containsString("token-macro"))); - + assertThat(new CLICommandInvoker(j, new InstallPluginCommand()). withStdin(ListPluginsCommandTest.class.getResourceAsStream("/plugins/token-macro.hpi")). invokeWithArgs("-name", "token-macro", "-deploy", "="), CLICommandInvoker.Matcher.succeeded()); assertNotNull(j.jenkins.getPluginManager().getPlugin("token-macro")); - + result = new CLICommandInvoker(j, new ListPluginsCommand()) .invoke() ; assertThat(result, CLICommandInvoker.Matcher.succeeded()); assertThat(result.stdout(), containsString("token-macro")); } - + @Test @Issue("SECURITY-771") public void onlyAccessibleForAdmin() { @@ -69,7 +69,7 @@ public void onlyAccessibleForAdmin() { .authorizedTo(Jenkins.READ) .invoke(); assertThat(result, CLICommandInvoker.Matcher.failedWith(6 /* not authorized */)); - + result = new CLICommandInvoker(j, new ListPluginsCommand()) .authorizedTo(Jenkins.ADMINISTER) .invoke() diff --git a/test/src/test/java/hudson/diagnosis/HudsonHomeDiskUsageMonitorTest.java b/test/src/test/java/hudson/diagnosis/HudsonHomeDiskUsageMonitorTest.java index dbb1ccaaea64..8ba103252d6c 100644 --- a/test/src/test/java/hudson/diagnosis/HudsonHomeDiskUsageMonitorTest.java +++ b/test/src/test/java/hudson/diagnosis/HudsonHomeDiskUsageMonitorTest.java @@ -61,7 +61,7 @@ public void flow() throws Exception { @Test public void noAccessForNonAdmin() throws Exception { ApiTokenTestHelper.enableLegacyBehavior(); - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); diff --git a/test/src/test/java/hudson/diagnosis/ReverseProxySetupMonitorTest.java b/test/src/test/java/hudson/diagnosis/ReverseProxySetupMonitorTest.java index ee5fbe24a621..d020f87975a4 100644 --- a/test/src/test/java/hudson/diagnosis/ReverseProxySetupMonitorTest.java +++ b/test/src/test/java/hudson/diagnosis/ReverseProxySetupMonitorTest.java @@ -50,9 +50,9 @@ protected JenkinsRule createJenkinsRule(Description description) { return j; } }; - + private String desiredContextPath; - + @Before public void resetContextPath() { this.desiredContextPath = "/jenkins"; @@ -133,7 +133,7 @@ public void evaluate() throws Throwable { WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); request.setAdditionalHeader("Referer", j.getURL() + "manage"); - // As the rootURL is missing the context, a regular test will fail + // As the rootURL is missing the context, a regular test will fail assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); // When testing with the context, it will be OK, allowing to display an additional message @@ -225,7 +225,7 @@ public void evaluate() throws Throwable { WebRequest request = new WebRequest(new URL(getRootUrlWithIp(j), getAdminMonitorTestUrl(j))); // referer using IP request.setAdditionalHeader("Referer", getRootUrlWithIp(j) + "manage"); - + // by default the JenkinsRule set the rootURL to localhost:/jenkins // even with similar request and referer, if the root URL is set, this will show a wrong proxy setting assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); @@ -267,7 +267,7 @@ public void evaluate() throws Throwable { // referer using IP request.setAdditionalHeader("Referer", getRootUrlWithIp(j) + "manage"); - // As the rootURL is missing the context, a regular test will fail + // As the rootURL is missing the context, a regular test will fail assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); // When testing with the context, it will be OK, allowing to display an additional message @@ -278,9 +278,9 @@ public void evaluate() throws Throwable { } private String getAdminMonitorTestUrl(JenkinsRule j) { - return j.jenkins.getAdministrativeMonitor(ReverseProxySetupMonitor.class.getName()).getUrl() + "/test"; + return j.jenkins.getAdministrativeMonitor(ReverseProxySetupMonitor.class.getName()).getUrl() + "/test"; } - + private URL getRootUrlWithIp(JenkinsRule j) throws Exception { return new URL(j.getURL().toString().replace("localhost", "127.0.0.1")); } diff --git a/test/src/test/java/hudson/diagnosis/TooManyJobsButNoViewTest.java b/test/src/test/java/hudson/diagnosis/TooManyJobsButNoViewTest.java index 2417d9b064f7..173a1fb439f5 100644 --- a/test/src/test/java/hudson/diagnosis/TooManyJobsButNoViewTest.java +++ b/test/src/test/java/hudson/diagnosis/TooManyJobsButNoViewTest.java @@ -79,7 +79,7 @@ private void verifyNoForm() throws IOException, SAXException { verifyNoForm(); } - + @Test public void systemReadNoViewAccessVerifyNoForm() throws Exception { final String READONLY = "readonly"; @@ -104,7 +104,7 @@ private void verifyNoMonitor(JenkinsRule.WebClient wc) throws IOException, SAXEx DomElement adminMonitorDiv = p.getElementById("tooManyJobsButNoView"); assertThat(adminMonitorDiv, is(nullValue())); } - + @Test public void systemReadVerifyForm() throws Exception { final String READONLY = "readonly"; @@ -132,5 +132,5 @@ private void verifyMonitor(JenkinsRule.WebClient wc) throws IOException, SAXExce assertThat(adminMonitorDiv, is(notNullValue())); assertThat(adminMonitorDiv.getTextContent(), is(notNullValue())); } - + } diff --git a/test/src/test/java/hudson/init/InitMilestoneTest.java b/test/src/test/java/hudson/init/InitMilestoneTest.java index 3783915ed36d..b46033b4ae4a 100644 --- a/test/src/test/java/hudson/init/InitMilestoneTest.java +++ b/test/src/test/java/hudson/init/InitMilestoneTest.java @@ -27,7 +27,7 @@ public void testInitMilestones() { } // Using @Initializer in static methods to check all the InitMilestones are loaded in all tests instances and make them fail, - // so using a TestExtension and checking only the InitMilestone after EXTENSION_AUGMENTED + // so using a TestExtension and checking only the InitMilestone after EXTENSION_AUGMENTED @TestExtension("testInitMilestones") public static class Initializers { private int order = 0; diff --git a/test/src/test/java/hudson/jobs/CreateItemTest.java b/test/src/test/java/hudson/jobs/CreateItemTest.java index af9019e35637..3de0a3c53132 100644 --- a/test/src/test/java/hudson/jobs/CreateItemTest.java +++ b/test/src/test/java/hudson/jobs/CreateItemTest.java @@ -105,8 +105,8 @@ public void vetoCreateItemFromCopy() throws Exception { .withThrowExceptionOnFailingStatusCode(false) .getPage(request); - assertEquals("Creating job from copy should fail.", - HttpURLConnection.HTTP_BAD_REQUEST, + assertEquals("Creating job from copy should fail.", + HttpURLConnection.HTTP_BAD_REQUEST, p.getWebResponse().getStatusCode()); assertThat(rule.jenkins.getItem("newJob"), nullValue()); } diff --git a/test/src/test/java/hudson/logging/LogRecorderManagerTest.java b/test/src/test/java/hudson/logging/LogRecorderManagerTest.java index 641c6fd1a2da..f7fb8341c164 100644 --- a/test/src/test/java/hudson/logging/LogRecorderManagerTest.java +++ b/test/src/test/java/hudson/logging/LogRecorderManagerTest.java @@ -24,17 +24,22 @@ package hudson.logging; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; +import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; import com.gargoylesoftware.htmlunit.html.HtmlForm; import com.gargoylesoftware.htmlunit.html.HtmlPage; import hudson.model.Computer; import hudson.remoting.VirtualChannel; import java.io.IOException; +import java.net.HttpURLConnection; import java.util.List; import java.util.logging.Level; import java.util.logging.LogRecord; @@ -70,6 +75,16 @@ public class LogRecorderManagerTest { assertEquals(Level.FINEST, logger.getLevel()); } + @Test public void loggerConfigNotFound() throws Exception { + HtmlPage page = j.createWebClient().goTo("log/levels"); + HtmlForm form = page.getFormByName("configLogger"); + form.getInputByName("name").setValueAttribute("foo.bar.zot"); + form.getSelectByName("level").getOptionByValue("finest").setSelected(true); + FailingHttpStatusCodeException e = assertThrows(FailingHttpStatusCodeException.class, () -> j.submit(form)); + assertThat(e.getStatusCode(), equalTo(HttpURLConnection.HTTP_BAD_REQUEST)); + assertThat(e.getResponse().getContentAsString(), containsString("A logger named \"foo.bar.zot\" does not exist")); + } + @Issue({"JENKINS-18274", "JENKINS-63458"}) @Test public void loggingOnSlaves() throws Exception { // TODO could also go through WebClient to assert that the config UI works diff --git a/test/src/test/java/hudson/model/AbstractBuildTest.java b/test/src/test/java/hudson/model/AbstractBuildTest.java index 12744e3a7f3d..6c0f2afe44b7 100644 --- a/test/src/test/java/hudson/model/AbstractBuildTest.java +++ b/test/src/test/java/hudson/model/AbstractBuildTest.java @@ -76,35 +76,35 @@ public class AbstractBuildTest { @ClassRule public static BuildWatcher buildWatcher = new BuildWatcher(); - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Test @Issue("JENKINS-30730") public void reportErrorShouldNotFailForNonPublisherClass() throws Exception { FreeStyleProject prj = j.createFreeStyleProject(); ErroneousJobProperty erroneousJobProperty = new ErroneousJobProperty(); prj.addProperty(erroneousJobProperty); - QueueTaskFuture future = prj.scheduleBuild2(0); + QueueTaskFuture future = prj.scheduleBuild2(0); assertThat("Build should be actually scheduled by Jenkins", future, notNullValue()); FreeStyleBuild build = future.get(); j.assertLogContains(ErroneousJobProperty.ERROR_MESSAGE, build); j.assertLogNotContains(ClassCastException.class.getName(), build); } - + /** * Job property, which always fails with an exception. */ public static class ErroneousJobProperty extends JobProperty { public static final String ERROR_MESSAGE = "This publisher fails by design"; - + @Override public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException { throw new IOException(ERROR_MESSAGE); } - + @TestExtension("reportErrorShouldNotFailForNonPublisherClass") public static class DescriptorImpl extends JobPropertyDescriptor {} } @@ -118,10 +118,10 @@ public void variablesResolved() throws Exception { j.buildAndAssertSuccess(project); - EnvVars envVars = builder.getEnvVars(); - assertEquals("value", envVars.get("KEY1")); - assertEquals("value", envVars.get("KEY2")); - } + EnvVars envVars = builder.getEnvVars(); + assertEquals("value", envVars.get("KEY1")); + assertEquals("value", envVars.get("KEY2")); + } /** * Makes sure that raw console output doesn't get affected by XML escapes. diff --git a/test/src/test/java/hudson/model/BuildExecutionTest.java b/test/src/test/java/hudson/model/BuildExecutionTest.java index 6effa4f5ee73..8505dae809dd 100644 --- a/test/src/test/java/hudson/model/BuildExecutionTest.java +++ b/test/src/test/java/hudson/model/BuildExecutionTest.java @@ -51,7 +51,7 @@ public class BuildExecutionTest { assertEquals(ws, lease.path); } } - + private static class BrokenPublisher extends Notifier { @Override public boolean needsToRunAfterFinalized() { throw new IllegalStateException("oops"); diff --git a/test/src/test/java/hudson/model/ComputerTest.java b/test/src/test/java/hudson/model/ComputerTest.java index e2262cfdabfc..2cef1e4837ba 100644 --- a/test/src/test/java/hudson/model/ComputerTest.java +++ b/test/src/test/java/hudson/model/ComputerTest.java @@ -98,7 +98,7 @@ public void testProhibitRenameOverExistingNode() throws Exception { Page page = j.submit(form); assertEquals(NOTE, HttpURLConnection.HTTP_BAD_REQUEST, page.getWebResponse().getStatusCode()); - assertThat(NOTE, page.getWebResponse().getContentAsString(), + assertThat(NOTE, page.getWebResponse().getContentAsString(), containsString("Agent called ‘nodeA’ already exists")); } diff --git a/test/src/test/java/hudson/model/DependencyGraphTest.java b/test/src/test/java/hudson/model/DependencyGraphTest.java index e37712cda353..02e2e49c0c42 100644 --- a/test/src/test/java/hudson/model/DependencyGraphTest.java +++ b/test/src/test/java/hudson/model/DependencyGraphTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Alan Harder - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java b/test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java index 528d99fe93a8..2ffa6c8cb60e 100644 --- a/test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java +++ b/test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -255,7 +255,7 @@ public void zipDownloadFileLeakMx() throws Exception { long finalOpenFds = getOpenFdCount(); if (finalOpenFds < initialOpenFds + numOfClicks) { - // when there was a file leak, the number of open file handle was always + // when there was a file leak, the number of open file handle was always // greater or equal to the number of download // in reverse, since the correction, the likelihood to overpass the limit was less than 1% freeFromLeak = true; diff --git a/test/src/test/java/hudson/model/DisplayNameTest.java b/test/src/test/java/hudson/model/DisplayNameTest.java index 1f1dd1d6c21a..7df1a5255bb3 100644 --- a/test/src/test/java/hudson/model/DisplayNameTest.java +++ b/test/src/test/java/hudson/model/DisplayNameTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright 2011 Yahoo!, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -47,11 +47,11 @@ public void testRenameJobWithNoDisplayName() throws Exception { final String newProjectName = "newProjectName"; FreeStyleProject project = j.createFreeStyleProject(projectName); assertEquals(projectName, project.getDisplayName()); - + project.renameTo(newProjectName); assertEquals(newProjectName, project.getDisplayName()); } - + @Test public void testRenameJobWithDisplayName() throws Exception { final String projectName = "projectName"; @@ -60,11 +60,11 @@ public void testRenameJobWithDisplayName() throws Exception { FreeStyleProject project = j.createFreeStyleProject(projectName); project.setDisplayName(displayName); assertEquals(displayName, project.getDisplayName()); - + project.renameTo(newProjectName); assertEquals(displayName, project.getDisplayName()); } - + @SuppressWarnings("rawtypes") @Test public void testCopyJobWithNoDisplayName() throws Exception { @@ -77,7 +77,7 @@ public void testCopyJobWithNoDisplayName() throws Exception { assertEquals(newProjectName, newProject.getName()); assertEquals(newProjectName, newProject.getDisplayName()); } - + @SuppressWarnings("rawtypes") @Test public void testCopyJobWithDisplayName() throws Exception { @@ -91,7 +91,7 @@ public void testCopyJobWithDisplayName() throws Exception { AbstractProject newProject = Jenkins.get().copy((AbstractProject)project, newProjectName); assertEquals(newProjectName, newProject.getName()); assertEquals(newProjectName, newProject.getDisplayName()); - + } @Issue("JENKINS-18074") diff --git a/test/src/test/java/hudson/model/FileParameterValueTest.java b/test/src/test/java/hudson/model/FileParameterValueTest.java index 519338a08e87..f282596f4314 100644 --- a/test/src/test/java/hudson/model/FileParameterValueTest.java +++ b/test/src/test/java/hudson/model/FileParameterValueTest.java @@ -55,39 +55,39 @@ public class FileParameterValueTest { @Rule public JenkinsRule j = new JenkinsRule(); - + @Rule public TemporaryFolder tmp = new TemporaryFolder(); - + @Test @Issue("SECURITY-1074") public void fileParameter_cannotCreateFile_outsideOfBuildFolder() throws Exception { // you can test the behavior before the correction by setting FileParameterValue.ALLOW_FOLDER_TRAVERSAL_OUTSIDE_WORKSPACE to true - + FilePath root = j.jenkins.getRootPath(); - + FreeStyleProject p = j.createFreeStyleProject(); p.addProperty(new ParametersDefinitionProperty(Collections.singletonList( new FileParameterDefinition("../../../../../root-level.txt", null) ))); - + assertThat(root.child("root-level.txt").exists(), equalTo(false)); - + String uploadedContent = "test-content"; File uploadedFile = tmp.newFile(); FileUtils.write(uploadedFile, uploadedContent, StandardCharsets.UTF_8); - + FreeStyleBuild build = p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction( new FileParameterValue("../../../../../root-level.txt", uploadedFile, "uploaded-file.txt") )).get(); - + assertThat(build.getResult(), equalTo(Result.FAILURE)); assertThat(root.child("root-level.txt").exists(), equalTo(false)); - + // ensure also the file is not reachable by request JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/parameter/..%2F..%2F..%2F..%2F..%2Froot-level.txt/uploaded-file.txt", uploadedContent); // encoding dots checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/parameter/%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Froot-level.txt/uploaded-file.txt", uploadedContent); @@ -161,132 +161,132 @@ private void checkUrlNot200AndNotContains(JenkinsRule.WebClient wc, String url, assertThat(pageForEncoded.getWebResponse().getStatusCode(), not(equalTo(200))); assertThat(pageForEncoded.getWebResponse().getContentAsString(), not(containsString(contentNotPresent))); } - + @Test @Issue("SECURITY-1074") public void fileParameter_cannotCreateFile_outsideOfBuildFolder_backslashEdition() throws Exception { Assume.assumeTrue("Backslashes are only dangerous on Windows", Functions.isWindows()); - + // you can test the behavior before the correction by setting FileParameterValue.ALLOW_FOLDER_TRAVERSAL_OUTSIDE_WORKSPACE to true - + FilePath root = j.jenkins.getRootPath(); - + FreeStyleProject p = j.createFreeStyleProject(); p.addProperty(new ParametersDefinitionProperty(Collections.singletonList( new FileParameterDefinition("..\\..\\..\\..\\..\\root-level.txt", null) ))); - + assertThat(root.child("root-level.txt").exists(), equalTo(false)); - + String uploadedContent = "test-content"; File uploadedFile = tmp.newFile(); FileUtils.write(uploadedFile, uploadedContent, StandardCharsets.UTF_8); - + FreeStyleBuild build = p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction( new FileParameterValue("..\\..\\..\\..\\..\\root-level.txt", uploadedFile, "uploaded-file.txt") )).get(); - + assertThat(build.getResult(), equalTo(Result.FAILURE)); assertThat(root.child("root-level.txt").exists(), equalTo(false)); - + // ensure also the file is not reachable by request JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/parameter/..\\..\\..\\..\\..\\root-level.txt/uploaded-file.txt", uploadedContent); checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/parameter/..%2F..%2F..%2F..%2F..%2Froot-level.txt/uploaded-file.txt", uploadedContent); } - + @Test @Issue("SECURITY-1074") public void fileParameter_withSingleDot() throws Exception { // this case was not working even before the patch - + FreeStyleProject p = j.createFreeStyleProject(); p.addProperty(new ParametersDefinitionProperty(Collections.singletonList( new FileParameterDefinition(".", null) ))); - + String uploadedContent = "test-content"; File uploadedFile = tmp.newFile(); FileUtils.write(uploadedFile, uploadedContent, StandardCharsets.UTF_8); - + FreeStyleBuild build = p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction( new FileParameterValue(".", uploadedFile, "uploaded-file.txt") )).get(); - + assertThat(build.getResult(), equalTo(Result.FAILURE)); - + // ensure also the file is not reachable by request JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/parameter/uploaded-file.txt", uploadedContent); checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/parameter/./uploaded-file.txt", uploadedContent); } - + @Test @Issue("SECURITY-1074") public void fileParameter_withDoubleDot() throws Exception { // this case was not working even before the patch - + FreeStyleProject p = j.createFreeStyleProject(); p.addProperty(new ParametersDefinitionProperty(Collections.singletonList( new FileParameterDefinition("..", null) ))); - + String uploadedContent = "test-content"; File uploadedFile = tmp.newFile(); FileUtils.write(uploadedFile, uploadedContent, StandardCharsets.UTF_8); - + FreeStyleBuild build = p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction( new FileParameterValue("..", uploadedFile, "uploaded-file.txt") )).get(); - + assertThat(build.getResult(), equalTo(Result.FAILURE)); - + // ensure also the file is not reachable by request JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/uploaded-file.txt", uploadedContent); checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/parameter/../uploaded-file.txt", uploadedContent); } - + @Test @Issue("SECURITY-1074") public void fileParameter_cannotEraseFile_outsideOfBuildFolder() throws Exception { // you can test the behavior before the correction by setting FileParameterValue.ALLOW_FOLDER_TRAVERSAL_OUTSIDE_WORKSPACE to true - + FilePath root = j.jenkins.getRootPath(); - + FreeStyleProject p = j.createFreeStyleProject(); p.addProperty(new ParametersDefinitionProperty(Collections.singletonList( new FileParameterDefinition("../../../../../root-level.txt", null) ))); - + assertThat(root.child("root-level.txt").exists(), equalTo(false)); String initialContent = "do-not-erase-me"; root.child("root-level.txt").write(initialContent, StandardCharsets.UTF_8.name()); - + String uploadedContent = "test-content"; File uploadedFile = tmp.newFile(); FileUtils.write(uploadedFile, uploadedContent, StandardCharsets.UTF_8); - + FreeStyleBuild build = p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction( new FileParameterValue("../../../../../root-level.txt", uploadedFile, "uploaded-file.txt") )).get(); - + assertThat(build.getResult(), equalTo(Result.FAILURE)); assertThat(root.child("root-level.txt").readToString(), equalTo(initialContent)); - + // ensure also the file is not reachable by request JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/parameter/..%2F..%2F..%2F..%2F..%2Froot-level.txt/uploaded-file.txt", uploadedContent); } - + @Test public void fileParameter_canStillUse_internalHierarchy() throws Exception { FreeStyleProject p = j.createFreeStyleProject(); @@ -294,28 +294,28 @@ public void fileParameter_canStillUse_internalHierarchy() throws Exception { new FileParameterDefinition("direct-child1.txt", null), new FileParameterDefinition("parent/child2.txt", null) ))); - + File uploadedFile1 = tmp.newFile(); FileUtils.write(uploadedFile1, "test1", StandardCharsets.UTF_8); File uploadedFile2 = tmp.newFile(); FileUtils.write(uploadedFile2, "test2", StandardCharsets.UTF_8); - + FreeStyleBuild build = j.assertBuildStatusSuccess(p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction( new FileParameterValue("direct-child1.txt", uploadedFile1, "uploaded-file-1.txt"), new FileParameterValue("parent/child2.txt", uploadedFile2, "uploaded-file-2.txt") ))); - + // files are correctly saved in the build "fileParameters" folder File directChild = new File(build.getRootDir(), "fileParameters/" + "direct-child1.txt"); assertTrue(directChild.exists()); - + File parentChild = new File(build.getRootDir(), "fileParameters/" + "parent/child2.txt"); assertTrue(parentChild.exists()); - + // both are correctly copied inside the workspace assertTrue(build.getWorkspace().child("direct-child1.txt").exists()); assertTrue(build.getWorkspace().child("parent").child("child2.txt").exists()); - + // and reachable using request JenkinsRule.WebClient wc = j.createWebClient(); HtmlPage workspacePage = wc.goTo(p.getUrl() + "ws"); diff --git a/test/src/test/java/hudson/model/FingerprintTest.java b/test/src/test/java/hudson/model/FingerprintTest.java index 03b0f3d4b39c..94c3c33fdc8f 100644 --- a/test/src/test/java/hudson/model/FingerprintTest.java +++ b/test/src/test/java/hudson/model/FingerprintTest.java @@ -145,10 +145,10 @@ public void shouldCreateFingerprintsForWorkspace() throws Exception { project.getBuildersList().add(new CreateFileBuilder("test.txt", "Hello, world!")); project.getPublishersList().add(new Fingerprinter("test.txt", false)); FreeStyleBuild build = rule.buildAndAssertSuccess(project); - + Fingerprint fp = getFingerprint(build, "test.txt"); } - + @Test public void shouldCreateFingerprintsForArtifacts() throws Exception { FreeStyleProject project = rule.createFreeStyleProject(); @@ -157,32 +157,32 @@ public void shouldCreateFingerprintsForArtifacts() throws Exception { archiver.setFingerprint(true); project.getPublishersList().add(archiver); FreeStyleBuild build = rule.buildAndAssertSuccess(project); - + Fingerprint fp = getFingerprint(build, "test.txt"); } - + @Test public void shouldCreateUsageLinks() throws Exception { - // Project 1 + // Project 1 FreeStyleProject project = createAndRunProjectWithPublisher("fpProducer", "test.txt"); final FreeStyleBuild build = project.getLastBuild(); - + // Project 2 FreeStyleProject project2 = rule.createFreeStyleProject(); project2.getBuildersList().add(new WorkspaceCopyFileBuilder("test.txt", project.getName(), build.getNumber())); project2.getPublishersList().add(new Fingerprinter("test.txt")); FreeStyleBuild build2 = rule.buildAndAssertSuccess(project2); - + Fingerprint fp = getFingerprint(build, "test.txt"); - + // Check references Fingerprint.BuildPtr original = fp.getOriginal(); assertEquals("Original reference contains a wrong job name", project.getName(), original.getName()); assertEquals("Original reference contains a wrong build number", build.getNumber(), original.getNumber()); - + Hashtable usages = fp.getUsages(); assertTrue("Usages do not have a reference to " + project, usages.containsKey(project.getName())); - assertTrue("Usages do not have a reference to " + project2, usages.containsKey(project2.getName())); + assertTrue("Usages do not have a reference to " + project2, usages.containsKey(project2.getName())); } @Test @@ -198,28 +198,28 @@ public void shouldThrowIOExceptionWhenFileIsInvalid() throws Exception { } fail("Expected IOException"); } - + @Test @Issue("SECURITY-153") public void shouldBeUnableToSeeJobsIfNoPermissions() throws Exception { - // Project 1 + // Project 1 final FreeStyleProject project1 = createAndRunProjectWithPublisher("fpProducer", "test.txt"); final FreeStyleBuild build = project1.getLastBuild(); - + // Project 2 final FreeStyleProject project2 = rule.createFreeStyleProject("project2"); project2.getBuildersList().add(new WorkspaceCopyFileBuilder("test.txt", project1.getName(), build.getNumber())); project2.getPublishersList().add(new Fingerprinter("test.txt")); final FreeStyleBuild build2 = rule.buildAndAssertSuccess(project2); - + // Get fingerprint final Fingerprint fp = getFingerprint(build, "test.txt"); - + // Init Users User user1 = User.getOrCreateByIdOrFullName("user1"); // can access project1 User user2 = User.getOrCreateByIdOrFullName("user2"); // can access project2 User user3 = User.getOrCreateByIdOrFullName("user3"); // cannot access anything - + // Project permissions setupProjectMatrixAuthStrategy(Jenkins.READ); setJobPermissionsOnce(project1, "user1", Item.READ, Item.DISCOVER); @@ -246,16 +246,16 @@ public void shouldBeUnableToSeeJobsIfNoPermissions() throws Exception { assertEquals("All usages should be invisible for user3", 0, fp._getUsages().size()); } } - + @Test public void shouldBeAbleToSeeOriginalWithDiscoverPermissionOnly() throws Exception { // Setup the environment final FreeStyleProject project = createAndRunProjectWithPublisher("project", "test.txt"); final FreeStyleBuild build = project.getLastBuild(); final Fingerprint fingerprint = getFingerprint(build, "test.txt"); - + // Init Users and security - User user1 = User.get("user1"); + User user1 = User.get("user1"); setupProjectMatrixAuthStrategy(Jenkins.READ, Item.DISCOVER); try (ACLContext acl = ACL.as(user1)) { @@ -266,20 +266,20 @@ public void shouldBeAbleToSeeOriginalWithDiscoverPermissionOnly() throws Excepti assertEquals("Usage ref in fingerprint should be visible to user1", 1, fingerprint._getUsages().size()); } } - + @Test public void shouldBeAbleToSeeFingerprintsInReadableFolder() throws Exception { final SecuredMockFolder folder = rule.jenkins.createProject(SecuredMockFolder.class, "folder"); final FreeStyleProject project = createAndRunProjectWithPublisher(folder, "project", "test.txt"); final FreeStyleBuild build = project.getLastBuild(); final Fingerprint fingerprint = getFingerprint(build, "test.txt"); - + // Init Users and security User user1 = User.getOrCreateByIdOrFullName("user1"); setupProjectMatrixAuthStrategy(false, Jenkins.READ, Item.DISCOVER); setJobPermissionsOnce(project, "user1", Item.DISCOVER); // Prevents the fallback to the folder ACL folder.setPermissions("user1", Item.READ); - + // Ensure we can read the original from user account try (ACLContext acl = ACL.as(user1)) { assertTrue("Test framework issue: User1 should be able to read the folder", folder.hasPermission(Item.READ)); @@ -293,18 +293,18 @@ public void shouldBeAbleToSeeFingerprintsInReadableFolder() throws Exception { assertThat("User should be unable do retrieve the job due to the missing read", original.getJob(), nullValue()); } } - + @Test public void shouldBeUnableToSeeFingerprintsInUnreadableFolder() throws Exception { final SecuredMockFolder folder = rule.jenkins.createProject(SecuredMockFolder.class, "folder"); final FreeStyleProject project = createAndRunProjectWithPublisher(folder, "project", "test.txt"); final FreeStyleBuild build = project.getLastBuild(); final Fingerprint fingerprint = getFingerprint(build, "test.txt"); - + // Init Users and security User user1 = User.getOrCreateByIdOrFullName("user1"); // can access project1 setupProjectMatrixAuthStrategy(Jenkins.READ, Item.DISCOVER); - + // Ensure we can read the original from user account try (ACLContext acl = ACL.as(user1)) { assertFalse("Test framework issue: User1 should be unable to read the folder", folder.hasPermission(Item.READ)); @@ -312,7 +312,7 @@ public void shouldBeUnableToSeeFingerprintsInUnreadableFolder() throws Exception assertEquals("No jobs should be visible to user1", 0, fingerprint._getUsages().size()); } } - + /** * A common non-admin user should not be able to see references to a * deleted job even if he used to have READ permissions before the deletion. @@ -325,7 +325,7 @@ public void commonUserShouldBeUnableToSeeReferencesOfDeletedJobs() throws Except FreeStyleProject project = createAndRunProjectWithPublisher("project", "test.txt"); FreeStyleBuild build = project.getLastBuild(); final Fingerprint fp = getFingerprint(build, "test.txt"); - + // Init Users and security User user1 = User.getOrCreateByIdOrFullName("user1"); setupProjectMatrixAuthStrategy(Jenkins.READ, Item.READ, Item.DISCOVER); @@ -336,14 +336,14 @@ public void commonUserShouldBeUnableToSeeReferencesOfDeletedJobs() throws Except assertEquals("No jobs should be visible to user1", 0, fp._getUsages().size()); } } - + @Test public void adminShouldBeAbleToSeeReferencesOfDeletedJobs() throws Exception { // Setup the environment final FreeStyleProject project = createAndRunProjectWithPublisher("project", "test.txt"); final FreeStyleBuild build = project.getLastBuild(); final Fingerprint fingerprint = getFingerprint(build, "test.txt"); - + // Init Users and security User user1 = User.getOrCreateByIdOrFullName("user1"); setupProjectMatrixAuthStrategy(Jenkins.ADMINISTER); @@ -592,7 +592,7 @@ public void checkArbitraryFingerprintConfigFileExistenceWithWebClient() throws E } assertTrue(targetFile.exists()); } - + @NonNull private Fingerprint getFingerprint(@CheckForNull Run run, @NonNull String filename) { assertNotNull("Input run is null", run); @@ -603,15 +603,15 @@ private Fingerprint getFingerprint(@CheckForNull Run run, @NonNull String assertNotNull("No reference to '" + filename + "' from the Fingerprint action", fp); return fp; } - + @NonNull - private FreeStyleProject createAndRunProjectWithPublisher(String projectName, String fpFileName) + private FreeStyleProject createAndRunProjectWithPublisher(String projectName, String fpFileName) throws Exception { return createAndRunProjectWithPublisher(null, projectName, fpFileName); } - + @NonNull - private FreeStyleProject createAndRunProjectWithPublisher(@CheckForNull MockFolder folder, + private FreeStyleProject createAndRunProjectWithPublisher(@CheckForNull MockFolder folder, String projectName, String fpFileName) throws Exception { final FreeStyleProject project; if (folder == null) { @@ -626,13 +626,13 @@ private FreeStyleProject createAndRunProjectWithPublisher(@CheckForNull MockFold rule.buildAndAssertSuccess(project); return project; } - + private void setupProjectMatrixAuthStrategy(@NonNull Permission ... permissions) { setupProjectMatrixAuthStrategy(true, permissions); } - + private void setupProjectMatrixAuthStrategy(boolean inheritFromFolders, @NonNull Permission ... permissions) { - ProjectMatrixAuthorizationStrategy str = inheritFromFolders + ProjectMatrixAuthorizationStrategy str = inheritFromFolders ? new ProjectMatrixAuthorizationStrategy() : new NoInheritanceProjectMatrixAuthorizationStrategy(); for (Permission p : permissions) { @@ -644,22 +644,22 @@ private void setupProjectMatrixAuthStrategy(boolean inheritFromFolders, @NonNull private void setJobPermissionsOnce(Job job, String username, @NonNull Permission ... s) throws IOException { assertThat("Cannot assign the property twice", job.getProperty(AuthorizationMatrixProperty.class), nullValue()); - + Map> permissions = new HashMap<>(); HashSet userSpec = new HashSet<>(Collections.singletonList(username)); for (Permission p : s) { permissions.put(p, userSpec); } - AuthorizationMatrixProperty property = new AuthorizationMatrixProperty(permissions); + AuthorizationMatrixProperty property = new AuthorizationMatrixProperty(permissions); job.addProperty(property); } - + /** * Security strategy, which prevents the permission inheritance from upper folders. */ private static class NoInheritanceProjectMatrixAuthorizationStrategy extends ProjectMatrixAuthorizationStrategy { - + @Override public ACL getACL(Job project) { AuthorizationMatrixProperty amp = project.getProperty(AuthorizationMatrixProperty.class); diff --git a/test/src/test/java/hudson/model/HelpLinkTest.java b/test/src/test/java/hudson/model/HelpLinkTest.java index 4f3a2e67a6be..1b80664ec1b8 100644 --- a/test/src/test/java/hudson/model/HelpLinkTest.java +++ b/test/src/test/java/hudson/model/HelpLinkTest.java @@ -32,15 +32,15 @@ "Executing negative(hudson.model.HelpLinkTest)@1" prio=5 tid=0x1 nid=NA waiting java.lang.Thread.State: WAITING - at java.lang.Object.wait(Object.java:-1) - at com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJobManagerImpl.waitForJobs(JavaScriptJobManagerImpl.java:200) - at com.gargoylesoftware.htmlunit.WebClient.waitForBackgroundJavaScript(WebClient.java:1843) - at com.gargoylesoftware.htmlunit.WebClientUtil.waitForJSExec(WebClientUtil.java:57) - at com.gargoylesoftware.htmlunit.WebClientUtil.waitForJSExec(WebClientUtil.java:46) - at com.gargoylesoftware.htmlunit.html.HtmlElementUtil.click(HtmlElementUtil.java:61) - at hudson.model.HelpLinkTest.clickAllHelpLinks(HelpLinkTest.java:70) - at hudson.model.HelpLinkTest.clickAllHelpLinks(HelpLinkTest.java:61) - at hudson.model.HelpLinkTest.negative(HelpLinkTest.java:106) + at java.lang.Object.wait(Object.java:-1) + at com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJobManagerImpl.waitForJobs(JavaScriptJobManagerImpl.java:200) + at com.gargoylesoftware.htmlunit.WebClient.waitForBackgroundJavaScript(WebClient.java:1843) + at com.gargoylesoftware.htmlunit.WebClientUtil.waitForJSExec(WebClientUtil.java:57) + at com.gargoylesoftware.htmlunit.WebClientUtil.waitForJSExec(WebClientUtil.java:46) + at com.gargoylesoftware.htmlunit.html.HtmlElementUtil.click(HtmlElementUtil.java:61) + at hudson.model.HelpLinkTest.clickAllHelpLinks(HelpLinkTest.java:70) + at hudson.model.HelpLinkTest.clickAllHelpLinks(HelpLinkTest.java:61) + at hudson.model.HelpLinkTest.negative(HelpLinkTest.java:106) In debugger, I can see that JavaScriptJobManagerImpl.waitForJobs is looping through yet each time getJobCount()>0 because there's always some window.setTimeout activities that appear to be scheduled. Common ones are: diff --git a/test/src/test/java/hudson/model/ItemsTest.java b/test/src/test/java/hudson/model/ItemsTest.java index 2bbc7b23f5a6..ab1cc3cb7ced 100644 --- a/test/src/test/java/hudson/model/ItemsTest.java +++ b/test/src/test/java/hudson/model/ItemsTest.java @@ -70,7 +70,7 @@ public class ItemsTest { public void setupLegacyBehavior(){ ApiTokenTestHelper.enableLegacyBehavior(); } - + @Test public void getAllItems() throws Exception { MockFolder d = r.createFolder("d"); MockFolder sub2 = d.createProject(MockFolder.class, "sub2"); @@ -171,7 +171,7 @@ public void allItems() throws Exception { assertFalse(new File(tmp, "foo/test/1").exists()); assertTrue(new File(tmp, "bar/test/1").exists()); } - + // TODO would be more efficient to run these all as a single test case, but after a few Jetty seems to stop serving new content and new requests just hang. private void overwriteTargetSetUp() throws Exception { diff --git a/test/src/test/java/hudson/model/JobTest.java b/test/src/test/java/hudson/model/JobTest.java index 926e8c85f479..70f7a9c726ad 100644 --- a/test/src/test/java/hudson/model/JobTest.java +++ b/test/src/test/java/hudson/model/JobTest.java @@ -1,19 +1,19 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi * Copyright (c) 2015 Christopher Simons - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -87,7 +87,7 @@ public class JobTest { @Test public void jobPropertySummaryIsShownInMainPage() throws Exception { AbstractProject project = j.createFreeStyleProject(); project.addProperty(new JobPropertyImpl("NeedleInPage")); - + HtmlPage page = j.createWebClient().getPage(project); WebAssert.assertTextPresent(page, "NeedleInPage"); } @@ -184,11 +184,11 @@ public void run() { public static class JobPropertyImpl extends JobProperty> { public static DescriptorImpl DESCRIPTOR = new DescriptorImpl(); private final String testString; - + public JobPropertyImpl(String testString) { this.testString = testString; } - + public String getTestString() { return testString; } @@ -224,7 +224,7 @@ public String getDisplayName() { @LocalData @Test public void configDotXmlPermission() throws Exception { ApiTokenTestHelper.enableLegacyBehavior(); - + j.jenkins.setCrumbIssuer(null); JenkinsRule.WebClient wc = j.createWebClient(); boolean saveEnabled = Item.EXTENDED_READ.getEnabled(); @@ -233,17 +233,17 @@ public String getDisplayName() { wc.assertFails("job/testJob/config.xml", HttpURLConnection.HTTP_FORBIDDEN); wc.setThrowExceptionOnFailingStatusCode(false); - + // Has CONFIGURE and EXTENDED_READ permission - wc.withBasicApiToken(User.getById("alice", true)); + wc.withBasicApiToken(User.getById("alice", true)); tryConfigDotXml(wc, HttpURLConnection.HTTP_INTERNAL_ERROR, "Both perms; should get 500"); // Has only CONFIGURE permission (this should imply EXTENDED_READ) - wc.withBasicApiToken(User.getById("bob", true)); + wc.withBasicApiToken(User.getById("bob", true)); tryConfigDotXml(wc, HttpURLConnection.HTTP_INTERNAL_ERROR, "Config perm should imply EXTENDED_READ"); // Has only EXTENDED_READ permission - wc.withBasicApiToken(User.getById("charlie", true)); + wc.withBasicApiToken(User.getById("charlie", true)); tryConfigDotXml(wc, HttpURLConnection.HTTP_FORBIDDEN, "No permission, should get 403"); } finally { Item.EXTENDED_READ.setEnabled(saveEnabled); @@ -254,13 +254,13 @@ private static void tryConfigDotXml(JenkinsRule.WebClient wc, int status, String // Verify we can GET the config.xml: Page p = wc.goTo("job/testJob/config.xml", "application/xml"); assertEquals("Retrieving config.xml should be ok", HttpURLConnection.HTTP_OK, p.getWebResponse().getStatusCode()); - + // This page is a simple form to POST to /job/testJob/config.xml // But it posts invalid data so we expect 500 if we have permission, 403 if not HtmlPage page = wc.goTo("userContent/post.html"); p = HtmlFormUtil.submit(page.getForms().get(0)); assertEquals(msg, status, p.getWebResponse().getStatusCode()); - + p = wc.goTo("logout"); assertEquals("To logout should be ok", HttpURLConnection.HTTP_OK, p.getWebResponse().getStatusCode()); } @@ -286,7 +286,7 @@ private static void tryConfigDotXml(JenkinsRule.WebClient wc, int status, String project.setDescription(null); assertEquals("", ((TextPage) wc.goTo("job/project/description", "text/plain")).getContent()); } - + @Test public void projectNamingStrategy() throws Exception { j.jenkins.setProjectNamingStrategy(new ProjectNamingStrategy.PatternProjectNamingStrategy("DUMMY.*", false)); try { diff --git a/test/src/test/java/hudson/model/ListViewTest.java b/test/src/test/java/hudson/model/ListViewTest.java index 1ed5dc322d86..4cc6e2b76007 100644 --- a/test/src/test/java/hudson/model/ListViewTest.java +++ b/test/src/test/java/hudson/model/ListViewTest.java @@ -87,7 +87,7 @@ public class ListViewTest { @Test public void nullJobNames() { assertTrue(j.jenkins.getView("v").getItems().isEmpty()); } - + @Test public void testJobLinksAreValid() throws Exception { /* @@ -101,7 +101,7 @@ public void testJobLinksAreValid() throws Exception { FreeStyleProject job1 = folder1.createProject(FreeStyleProject.class, "job1"); MockFolder folder2 = folder1.createProject(MockFolder.class, "folder2"); FreeStyleProject job2 = folder2.createProject(FreeStyleProject.class, "job2"); - + ListView lv = new ListView("myview"); lv.setRecurse(true); lv.setIncludeRegex(".*"); @@ -119,7 +119,7 @@ public void testJobLinksAreValid() throws Exception { checkLinkFromItemExistsAndIsValid(folder2, folder1, folder1, webClient); checkLinkFromViewExistsAndIsValid(job2, folder1, lv2, webClient); } - + private void checkLinkFromViewExistsAndIsValid(Item item, ItemGroup ig, View view, WebClient webClient) throws IOException, SAXException { HtmlPage page = webClient.goTo(view.getUrl()); HtmlAnchor link = page.getAnchorByText(Functions.getRelativeDisplayNameFrom(item, ig)); diff --git a/test/src/test/java/hudson/model/MyViewTest.java b/test/src/test/java/hudson/model/MyViewTest.java index efac83311e09..15b6a2bd4a76 100644 --- a/test/src/test/java/hudson/model/MyViewTest.java +++ b/test/src/test/java/hudson/model/MyViewTest.java @@ -49,7 +49,7 @@ * @author Lucie Votypkova */ public class MyViewTest { - + @Rule public JenkinsRule rule = new JenkinsRule(); @@ -60,11 +60,11 @@ public class MyViewTest { public void setup() { rule.jenkins.setSecurityRealm(rule.createDummySecurityRealm()); } - + @Test public void testContains() throws Exception{ - - GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); + + GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); rule.jenkins.setAuthorizationStrategy(auth); User user = User.getOrCreateByIdOrFullName("User1"); FreeStyleProject job = rule.createFreeStyleProject("job"); @@ -76,7 +76,7 @@ public void testContains() throws Exception{ auth.add(Item.CONFIGURE, "User1"); assertTrue("View " + view.getDisplayName() + " contain job " + job.getDisplayName(), view.contains(job)); } - + @Test public void testDoCreateItem() throws Exception{ logs.record(AbstractItem.class, Level.ALL); @@ -95,12 +95,12 @@ public void testDoCreateItem() throws Exception{ assumeThat("TODO sometimes on Windows CI the submission does not seem to be really processed (most log messages are missing)", item, notNullValue()); assertThat(view.getItems(), contains(equalTo(item))); } - + @Test public void testGetItems() throws IOException { User user = User.getOrCreateByIdOrFullName("User1"); - GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); - rule.jenkins.setAuthorizationStrategy(auth); + GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); + rule.jenkins.setAuthorizationStrategy(auth); FreeStyleProject job2 = rule.createFreeStyleProject("job2"); FreeStyleProject job = rule.createFreeStyleProject("job"); MyView view = new MyView("My", rule.jenkins); @@ -112,6 +112,6 @@ public void testGetItems() throws IOException { assertTrue("View " + view.getDisplayName() + " should contain job " + job.getDisplayName(), view.getItems().contains(job)); assertTrue("View " + view.getDisplayName() + " should contain job " + job2.getDisplayName(), view.getItems().contains(job2)); } - - + + } diff --git a/test/src/test/java/hudson/model/MyViewsPropertyTest.java b/test/src/test/java/hudson/model/MyViewsPropertyTest.java index 935ed5ab36de..372643d60cff 100644 --- a/test/src/test/java/hudson/model/MyViewsPropertyTest.java +++ b/test/src/test/java/hudson/model/MyViewsPropertyTest.java @@ -47,10 +47,10 @@ * @author Lucie Votypkova */ public class MyViewsPropertyTest { - + @Rule public JenkinsRule rule = new JenkinsRule(); - + @Test public void testReadResolve() throws IOException { User user = User.getOrCreateByIdOrFullName("User"); @@ -84,7 +84,7 @@ public void testSave() throws IOException { assertEquals("Property should have primary view " + view.name + " instead of " + property.getPrimaryViewName(), view.name, property.getPrimaryViewName()); } */ - + @Test public void testGetViews() throws IOException { User user = User.getOrCreateByIdOrFullName("User"); @@ -96,7 +96,7 @@ public void testGetViews() throws IOException { property.addView(view); assertTrue("Property should contain " + view.name, property.getViews().contains(view)); } - + @Test public void testGetView() throws IOException { User user = User.getOrCreateByIdOrFullName("User"); @@ -109,7 +109,7 @@ public void testGetView() throws IOException { property.addView(view); assertEquals("Property should contain " + view.name, view, property.getView(view.name)); } - + @Test public void testGetPrimaryView() throws IOException { User user = User.getOrCreateByIdOrFullName("User"); @@ -123,7 +123,7 @@ public void testGetPrimaryView() throws IOException { property.setPrimaryViewName(view.name); assertEquals("Property should have primary view " + view.name + " instead of " + property.getPrimaryView().name, view, property.getPrimaryView()); } - + @Test public void testCanDelete() throws IOException { User user = User.getOrCreateByIdOrFullName("User"); @@ -183,8 +183,8 @@ public void testOnViewRenamed() throws IOException, FormException { View view = new ListView("foo", property); property.addView(view); property.setPrimaryViewName(view.name); - view.rename("primary-renamed"); - assertEquals("Property should rename its primary view ", "primary-renamed", property.getPrimaryViewName()); + view.rename("primary-renamed"); + assertEquals("Property should rename its primary view ", "primary-renamed", property.getPrimaryViewName()); } @Test @@ -219,7 +219,7 @@ public void testDoCreateView() throws Exception { form.getInputByName("name").setValueAttribute("foo"); form.getRadioButtonsByName("mode").get(0).setChecked(true); rule.submit(form); - assertNotNull("Property should contain view foo", property.getView("foo")); + assertNotNull("Property should contain view foo", property.getView("foo")); } rule.jenkins.reload(); { @@ -248,8 +248,8 @@ public void testCheckPermission() throws IOException { MyViewsProperty property = new MyViewsProperty(AllView.DEFAULT_VIEW_NAME); property.readResolve(); property.setUser(user); - GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); - rule.jenkins.setAuthorizationStrategy(auth); + GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); + rule.jenkins.setAuthorizationStrategy(auth); user.addProperty(property); boolean ex = false; SecurityContextHolder.getContext().setAuthentication(user2.impersonate2()); @@ -285,8 +285,8 @@ public void testHasPermission() throws IOException { MyViewsProperty property = new MyViewsProperty(AllView.DEFAULT_VIEW_NAME); property.readResolve(); property.setUser(user); - GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); - rule.jenkins.setAuthorizationStrategy(auth); + GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); + rule.jenkins.setAuthorizationStrategy(auth); user.addProperty(property); SecurityContextHolder.getContext().setAuthentication(user2.impersonate2()); assertFalse("User User2 should not configure permission for user User",property.hasPermission(Permission.CONFIGURE)); @@ -310,5 +310,5 @@ public void shouldNotFailWhenMigratingLegacyViewsWithoutPrimaryOne() throws IOEx property.addView(new AllView("foobar")); property.readResolve(); } - + } diff --git a/test/src/test/java/hudson/model/ParametersTest.java b/test/src/test/java/hudson/model/ParametersTest.java index eab06e2b9d87..0fe26d4615b6 100644 --- a/test/src/test/java/hudson/model/ParametersTest.java +++ b/test/src/test/java/hudson/model/ParametersTest.java @@ -93,9 +93,7 @@ public void parameterTypes() throws Exception { assertEquals("run", ((HtmlElement) DomNodeUtil.selectSingleNode(element.getParentNode(), "div[contains(@class, 'jenkins-form-label')]")).getTextContent()); j.submit(form); - Queue.Item q = j.jenkins.getQueue().getItem(project); - if (q != null) q.getFuture().get(); - else Thread.sleep(1000); + j.waitUntilNoActivity(); assertEquals("newValue", builder.getEnvVars().get("STRING")); assertEquals("true", builder.getEnvVars().get("BOOLEAN")); @@ -130,9 +128,7 @@ public void choiceWithLTGT() throws Exception { opt.setSelected(true); j.submit(form); - Queue.Item q = j.jenkins.getQueue().getItem(project); - if (q != null) q.getFuture().get(); - else Thread.sleep(1000); + j.waitUntilNoActivity(); assertNotNull(builder.getEnvVars()); assertEquals("Choice <2>", builder.getEnvVars().get("CHOICE")); @@ -208,9 +204,7 @@ public void fileParameterNotSet() throws Exception { HtmlForm form = page.getFormByName("parameters"); j.submit(form); - Queue.Item q = j.jenkins.getQueue().getItem(project); - if (q != null) q.getFuture().get(); - else Thread.sleep(1000); + j.waitUntilNoActivity(); assertFalse("file must not exist", project.getSomeWorkspace().child("filename").exists()); } @@ -234,6 +228,7 @@ public void unicodeParametersArePresetCorrectly() throws Exception { wc.setThrowExceptionOnFailingStatusCode(true); final HtmlForm form = page.getFormByName("parameters"); HtmlFormUtil.submit(form, HtmlFormUtil.getButtonByCaption(form, "Build")); + j.waitUntilNoActivity(); } @Issue("SECURITY-353") diff --git a/test/src/test/java/hudson/model/PasswordParameterDefinitionTest.java b/test/src/test/java/hudson/model/PasswordParameterDefinitionTest.java index 67ee5e9638eb..6541af0682a2 100644 --- a/test/src/test/java/hudson/model/PasswordParameterDefinitionTest.java +++ b/test/src/test/java/hudson/model/PasswordParameterDefinitionTest.java @@ -53,7 +53,7 @@ public class PasswordParameterDefinitionTest { @Issue("JENKINS-36476") @Test public void defaultValueAlwaysAvailable() throws Exception { ApiTokenTestHelper.enableLegacyBehavior(); - + j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy(). grant(Jenkins.ADMINISTER).everywhere().to("admin"). diff --git a/test/src/test/java/hudson/model/ProjectTest.java b/test/src/test/java/hudson/model/ProjectTest.java index 2873e43a7c35..1bf57cf06a68 100644 --- a/test/src/test/java/hudson/model/ProjectTest.java +++ b/test/src/test/java/hudson/model/ProjectTest.java @@ -108,12 +108,12 @@ * @author Lucie Votypkova */ public class ProjectTest { - + @Rule public JenkinsRule j = new JenkinsRule(); public static boolean createAction = false; public static boolean getFilePath = false; public static boolean createSubTask = false; - + @Test public void testSave() throws IOException, InterruptedException, ReactorException { FreeStyleProject p = j.createFreeStyleProject("project"); @@ -126,7 +126,7 @@ public void testSave() throws IOException, InterruptedException, ReactorExceptio assertEquals("All persistent data should be saved.", 5, p.nextBuildNumber); assertTrue("All persistent data should be saved", p.disabled); } - + @Test public void testOnCreateFromScratch() throws Exception{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -138,7 +138,7 @@ public void testOnCreateFromScratch() throws Exception{ assertNotNull("Project should have transient action TransientAction.", p.getAction(TransientAction.class)); createAction = false; } - + @Test public void testOnLoad() throws Exception{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -151,7 +151,7 @@ public void testOnLoad() throws Exception{ assertNotNull("Project should have Transient Action TransientAction.", p.getAction(TransientAction.class)); createAction = false; } - + @Test public void testGetEnvironment() throws Exception{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -161,7 +161,7 @@ public void testGetEnvironment() throws Exception{ EnvVars var = p.getEnvironment(slave, TaskListener.NULL); assertEquals("Environment should have set jdk.", "some_java", var.get("jdk")); } - + @Test public void testPerformDelete() throws Exception{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -169,7 +169,7 @@ public void testPerformDelete() throws Exception{ assertFalse("Project should be deleted from disk.", p.getConfigFile().exists()); assertTrue("Project should be disabled when deleting start.", p.isDisabled()); } - + @Test public void testGetAssignedLabel() throws Exception{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -181,7 +181,7 @@ public void testGetAssignedLabel() throws Exception{ p.setAssignedLabel(slave.getSelfLabel()); assertEquals("Project should have self label of slave", slave.getSelfLabel(), p.getAssignedLabel()); } - + @Test public void testGetAssignedLabelString() throws Exception{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -193,7 +193,7 @@ public void testGetAssignedLabelString() throws Exception{ assertEquals("Project should return name of slave.", slave.getSelfLabel().name, p.getAssignedLabelString()); } - + @Test public void testGetSomeWorkspace() throws Exception{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -206,7 +206,7 @@ public void testGetSomeWorkspace() throws Exception{ j.buildAndAssertSuccess(p); assertNotNull("Project should has any workspace.", p.getSomeWorkspace()); } - + @Test public void testGetSomeBuildWithWorkspace() throws Exception{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -231,7 +231,7 @@ public void testGetSomeBuildWithWorkspace() throws Exception{ p.doDoWipeOutWorkspace(); wc.assertFails("job/project/ws/some.log", 404); } - + @Test public void testGetQuietPeriod() throws IOException{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -241,7 +241,7 @@ public void testGetQuietPeriod() throws IOException{ p.setQuietPeriod(10); assertEquals("Quiet period was set.", 10, p.getQuietPeriod()); } - + @Test public void testGetScmCheckoutStrategy() throws IOException{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -251,7 +251,7 @@ public void testGetScmCheckoutStrategy() throws IOException{ p.setScmCheckoutStrategy(strategy); assertEquals("Project should return its scm checkout strategy if this strategy is not null", strategy, p.getScmCheckoutStrategy()); } - + @Test public void testGetScmCheckoutRetryCount() throws Exception{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -266,7 +266,7 @@ public void testGetScmCheckoutRetryCount() throws Exception{ j.submit(form); assertEquals("Scm retry count was set.", 7, p.getScmCheckoutRetryCount()); } - + @Test public void isBuildable() throws IOException{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -279,7 +279,7 @@ public void isBuildable() throws IOException{ p2.save(); assertTrue("Project should be buildable after save.", p2.isBuildable()); } - + @Test public void testMakeDisabled() throws IOException{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -293,7 +293,7 @@ public void testMakeDisabled() throws IOException{ p.makeDisabled(true); assertNull("Project should be canceled.", Queue.getInstance().getItem(p)); } - + @Test public void testAddProperty() throws IOException{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -303,7 +303,7 @@ public void testAddProperty() throws IOException{ assertNotNull("Project does not contain added property.", p.getProperty(prop.getClass())); assertNotNull("Project did not update transient actions.", p.getAction(TransientAction.class)); } - + @Test public void testScheduleBuild2() throws IOException, InterruptedException{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -319,7 +319,7 @@ public void testScheduleBuild2() throws IOException, InterruptedException{ assertNotNull("Build should be done or in progress.", p.getLastBuild()); } - + @Test public void testSchedulePolling() throws IOException, ANTLRException{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -331,7 +331,7 @@ public void testSchedulePolling() throws IOException, ANTLRException{ p.disable(); assertFalse("Project should not schedule polling because project is disabled.", p.schedulePolling()); } - + @Test public void testSaveAfterSet() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); @@ -353,7 +353,7 @@ public void testSaveAfterSet() throws Exception { assertNotNull("Project did not save jdk", p.getJDK()); assertEquals("Project did not save custom workspace.", "/some/path", p.getCustomWorkspace()); } - + @Test public void testGetActions() throws IOException{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -409,7 +409,7 @@ private void assertInstanceOf(String msg, Object o, Class t) { return; fail(msg + ": " + o); } - + @Test public void testGetSubTasks() throws IOException{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -427,9 +427,9 @@ public void testGetSubTasks() throws IOException{ createSubTask = false; assertTrue("Project should return subtasks provided by SubTaskContributor.", containsSubTaskImpl2); assertTrue("Project should return subtasks provided by JobProperty.", containsSubTaskImpl); - + } - + @Test public void testCreateExecutable() throws IOException{ FreeStyleProject p = j.createFreeStyleProject("project"); @@ -441,9 +441,9 @@ public void testCreateExecutable() throws IOException{ build = p.createExecutable(); assertNull("Disabled project should not create executable.", build); assertEquals("Next build number should not be increased.", 2, p.nextBuildNumber); - + } - + @Test public void testCheckout() throws Exception{ SCM scm = new NullSCM(); @@ -484,7 +484,7 @@ public void testPoll() throws Exception{ j.buildAndAssertSuccess(p); assertEquals("Project should have polling result significant", PollingResult.Change.SIGNIFICANT, p.poll(TaskListener.NULL).change); } - + @Test public void testHasParticipant() throws Exception{ User user = User.get("John Smith", true, Collections.emptyMap()); @@ -495,11 +495,11 @@ public void testHasParticipant() throws Exception{ j.buildAndAssertSuccess(project2); assertFalse("Project should not have any participant.", project2.hasParticipant(user)); scm.addChange().withAuthor(user.getId()); - project.setScm(scm); + project.setScm(scm); j.buildAndAssertSuccess(project); assertTrue("Project should have participant.", project.hasParticipant(user)); } - + @Test public void testGetRelationship() throws Exception{ final FreeStyleProject upstream = j.createFreeStyleProject("upstream"); @@ -539,25 +539,25 @@ public void testGetRelationship() throws Exception{ assertEquals("downstream #4 should depend only on upstream #5", 4, relationship.get(5).min()); assertEquals("downstream #4 should depend only on upstream #5", 4, relationship.get(5).max()-1); } - + @Test public void testDoCancelQueue() throws Exception{ FreeStyleProject project = j.createFreeStyleProject("project"); - GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); + GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); j.jenkins.setAuthorizationStrategy(auth); j.jenkins.setCrumbIssuer(null); HudsonPrivateSecurityRealm realm = new HudsonPrivateSecurityRealm(false); - j.jenkins.setSecurityRealm(realm); + j.jenkins.setSecurityRealm(realm); User user = realm.createAccount("John Smith", "password"); try (ACLContext as = ACL.as(user)) { assertThrows("User should not have permission to build project", AccessDeniedException3.class, () -> project.doCancelQueue(null, null)); } } - + @Test public void testDoDoDelete() throws Exception{ FreeStyleProject project = j.createFreeStyleProject("project"); - GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); + GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); j.jenkins.setAuthorizationStrategy(auth); j.jenkins.setCrumbIssuer(null); j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); @@ -583,15 +583,15 @@ public void testDoDoDelete() throws Exception{ assertNull("Project should be deleted form memory.", j.jenkins.getItem(project.getDisplayName())); assertFalse("Project should be deleted form disk.", project.getRootDir().exists()); } - + @Test public void testDoDoWipeOutWorkspace() throws Exception{ FreeStyleProject project = j.createFreeStyleProject("project"); - GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); + GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); j.jenkins.setAuthorizationStrategy(auth); j.jenkins.setCrumbIssuer(null); HudsonPrivateSecurityRealm realm = new HudsonPrivateSecurityRealm(false); - j.jenkins.setSecurityRealm(realm); + j.jenkins.setSecurityRealm(realm); User user = realm.createAccount("John Smith", "password"); try (ACLContext as = ACL.as(user)) { assertThrows("User should not have permission to build project", AccessDeniedException3.class, project::doDoWipeOutWorkspace); @@ -615,15 +615,15 @@ public void testDoDoWipeOutWorkspace() throws Exception{ Thread.sleep(500); assertFalse("Workspace should not exist.", project.getSomeWorkspace().exists()); } - + @Test public void testDoDisable() throws Exception{ FreeStyleProject project = j.createFreeStyleProject("project"); - GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); + GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); j.jenkins.setAuthorizationStrategy(auth); j.jenkins.setCrumbIssuer(null); HudsonPrivateSecurityRealm realm = new HudsonPrivateSecurityRealm(false); - j.jenkins.setSecurityRealm(realm); + j.jenkins.setSecurityRealm(realm); User user = realm.createAccount("John Smith", "password"); try (ACLContext as = ACL.as(user)) { assertThrows("User should not have permission to build project", AccessDeniedException3.class, project::doDisable); @@ -644,11 +644,11 @@ public void testDoDisable() throws Exception{ } assertTrue("Project should be disabled.", project.isDisabled()); } - + @Test public void testDoEnable() throws Exception{ FreeStyleProject project = j.createFreeStyleProject("project"); - GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); + GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); j.jenkins.setAuthorizationStrategy(auth); j.jenkins.setCrumbIssuer(null); HudsonPrivateSecurityRealm realm = new HudsonPrivateSecurityRealm(false); @@ -676,36 +676,36 @@ public void testDoEnable() throws Exception{ } assertFalse("Project should be enabled.", project.isDisabled()); } - + /** * Job is un-restricted (no nabel), this is submitted to queue, which spawns an on demand slave */ @Test public void testJobSubmittedShouldSpawnCloud() throws Exception { /* - * Setup a project with an SCM. Jenkins should have no executors in itself. + * Setup a project with an SCM. Jenkins should have no executors in itself. */ - FreeStyleProject proj = j.createFreeStyleProject("JENKINS-21394-spawn"); + FreeStyleProject proj = j.createFreeStyleProject("JENKINS-21394-spawn"); RequiresWorkspaceSCM requiresWorkspaceScm = new RequiresWorkspaceSCM(true); - proj.setScm(requiresWorkspaceScm); - j.jenkins.setNumExecutors(0); + proj.setScm(requiresWorkspaceScm); + j.jenkins.setNumExecutors(0); /* * We have a cloud */ DummyCloudImpl2 c2 = new DummyCloudImpl2(j, 0); - c2.label = new LabelAtom("test-cloud-label"); + c2.label = new LabelAtom("test-cloud-label"); j.jenkins.clouds.add(c2); - + SCMTrigger t = new SCMTrigger("@daily", true); t.start(proj, true); proj.addTrigger(t); t.new Runner().run(); - + Thread.sleep(1000); //Assert that the job IS submitted to Queue. - assertEquals(1, j.jenkins.getQueue().getItems().length); + assertEquals(1, j.jenkins.getQueue().getItems().length); } - + /** * Job is restricted, but label can not be provided by any cloud, only normal agents. Then job will not submit, because no slave is available. */ @@ -714,68 +714,68 @@ public void testUnrestrictedJobNoLabelByCloudNoQueue() throws Exception { assertTrue(j.jenkins.clouds.isEmpty()); //Create slave. (Online) Slave s1 = j.createOnlineSlave(); - + //Create a project, and bind the job to the created slave FreeStyleProject proj = j.createFreeStyleProject("JENKINS-21394-noqueue"); proj.setAssignedLabel(s1.getSelfLabel()); - + //Add an SCM to the project. We require a workspace for the poll RequiresWorkspaceSCM requiresWorkspaceScm = new RequiresWorkspaceSCM(true); proj.setScm(requiresWorkspaceScm); - - j.buildAndAssertSuccess(proj); + + j.buildAndAssertSuccess(proj); //Now create another slave. And restrict the job to that slave. The slave is offline, leaving the job with no assignable nodes. - //We tell our mock SCM to return that it has got changes. But since there are no agents, we get the desired result. + //We tell our mock SCM to return that it has got changes. But since there are no agents, we get the desired result. Slave s2 = j.createSlave(); proj.setAssignedLabel(s2.getSelfLabel()); requiresWorkspaceScm.hasChange = true; - + //Poll (We now should have NO online agents, this should now return NO_CHANGES. PollingResult pr = proj.poll(j.createTaskListener()); assertFalse(pr.hasChanges()); - + SCMTrigger t = new SCMTrigger("@daily", true); t.start(proj, true); proj.addTrigger(t); - + t.new Runner().run(); - + /* * Assert that the log contains the correct message. */ HtmlPage log = j.createWebClient().getPage(proj, "scmPollLog"); String logastext = log.asNormalizedText(); assertTrue(logastext.contains("(" + AbstractProject.WorkspaceOfflineReason.all_suitable_nodes_are_offline.name() + ")")); - + } - + /** * Job is restricted. Label is on slave that can be started in cloud. Job is submitted to queue, which spawns an on demand slave. */ @Test - public void testRestrictedLabelOnSlaveYesQueue() throws Exception { + public void testRestrictedLabelOnSlaveYesQueue() throws Exception { FreeStyleProject proj = j.createFreeStyleProject("JENKINS-21394-yesqueue"); RequiresWorkspaceSCM requiresWorkspaceScm = new RequiresWorkspaceSCM(true); - proj.setScm(requiresWorkspaceScm); + proj.setScm(requiresWorkspaceScm); j.jenkins.setNumExecutors(0); - + /* * We have a cloud */ DummyCloudImpl2 c2 = new DummyCloudImpl2(j, 0); - c2.label = new LabelAtom("test-cloud-label"); + c2.label = new LabelAtom("test-cloud-label"); j.jenkins.clouds.add(c2); proj.setAssignedLabel(c2.label); - + SCMTrigger t = new SCMTrigger("@daily", true); t.start(proj, true); proj.addTrigger(t); t.new Runner().run(); - + Thread.sleep(1000); //The job should be in queue - assertEquals(1, j.jenkins.getQueue().getItems().length); + assertEquals(1, j.jenkins.getQueue().getItems().length); } @Issue("JENKINS-22750") @@ -783,11 +783,11 @@ public void testRestrictedLabelOnSlaveYesQueue() throws Exception { public void testMasterJobPutInQueue() throws Exception { FreeStyleProject proj = j.createFreeStyleProject("JENKINS-21394-yes-master-queue"); RequiresWorkspaceSCM requiresWorkspaceScm = new RequiresWorkspaceSCM(true); - proj.setAssignedLabel(null); - proj.setScm(requiresWorkspaceScm); - j.jenkins.setNumExecutors(1); + proj.setAssignedLabel(null); + proj.setScm(requiresWorkspaceScm); + j.jenkins.setNumExecutors(1); proj.setScm(requiresWorkspaceScm); - + //First build is not important j.buildAndAssertSuccess(proj); @@ -801,9 +801,9 @@ public void testMasterJobPutInQueue() throws Exception { } public static class TransientAction extends InvisibleAction{ - + } - + @TestExtension public static class TransientActionFactoryImpl extends TransientProjectActionFactory{ @@ -814,25 +814,25 @@ public Collection createFor(AbstractProject target) { actions.add(new TransientAction()); return actions; } - + } - - @TestExtension + + @TestExtension public static class RequiresWorkspaceSCM extends NullSCM { - + public boolean hasChange = false; - + public RequiresWorkspaceSCM() { } - + public RequiresWorkspaceSCM(boolean hasChange) { this.hasChange = hasChange; } - + @Override public boolean pollChanges(AbstractProject project, Launcher launcher, FilePath workspace, TaskListener listener) { return hasChange; } - + @Override public boolean requiresWorkspaceForPolling(){ return true; @@ -840,7 +840,7 @@ public boolean requiresWorkspaceForPolling(){ @Override public SCMDescriptor getDescriptor() { return new SCMDescriptor(null) {}; } - + @Override protected PollingResult compareRemoteRevisionWith(AbstractProject project, Launcher launcher, FilePath workspace, TaskListener listener, SCMRevisionState baseline) { if(!hasChange) { @@ -849,7 +849,7 @@ protected PollingResult compareRemoteRevisionWith(AbstractProject project, Launc return PollingResult.SIGNIFICANT; } } - + @TestExtension public static class AlwaysChangedSCM extends NullSCM { @@ -857,7 +857,7 @@ public static class AlwaysChangedSCM extends NullSCM { public boolean pollChanges(AbstractProject project, Launcher launcher, FilePath workspace, TaskListener listener) { return true; } - + @Override public boolean requiresWorkspaceForPolling(){ return false; @@ -867,9 +867,9 @@ public boolean requiresWorkspaceForPolling(){ protected PollingResult compareRemoteRevisionWith(AbstractProject project, Launcher launcher, FilePath workspace, TaskListener listener, SCMRevisionState baseline) { return PollingResult.SIGNIFICANT; } - + } - + @TestExtension public static class WorkspaceBrowserImpl extends WorkspaceBrowser{ @@ -879,18 +879,18 @@ public FilePath getWorkspace(Job job) { return new FilePath(new File("some_file_path")); return null; } - + } - + public static class SCMCheckoutStrategyImpl extends DefaultSCMCheckoutStrategyImpl implements Serializable{ - + public SCMCheckoutStrategyImpl(){ - + } } - + public static class JobPropertyImp extends JobProperty{ @Override @@ -899,10 +899,10 @@ public Collection getSubTasks() { list.add(new SubTaskImpl()); return list; } - - + + } - + @TestExtension public static class SubTaskContributorImpl extends SubTaskContributor{ @@ -915,13 +915,13 @@ public Collection forProject(AbstractProject p) { return list; } } - + public static class SubTaskImpl2 extends SubTaskImpl{ - + } - + public static class SubTaskImpl implements SubTask{ - + public String projectName; @Override @@ -939,13 +939,13 @@ public String getDisplayName() { return "some task"; } - + } - + public class ActionImpl extends InvisibleAction{ - + } - + @TestExtension public static class DummyCloudImpl2 extends Cloud { private final transient JenkinsRule caller; @@ -966,8 +966,8 @@ public static class DummyCloudImpl2 extends Cloud { * Only reacts to provisioning for this label. */ public Label label; - - public DummyCloudImpl2() { + + public DummyCloudImpl2() { super("test"); this.delay = 0; this.caller = null; @@ -996,7 +996,7 @@ public Collection provision(Label label, int excess @Override public boolean canProvision(Label label) { - //This cloud can ALWAYS provision + //This cloud can ALWAYS provision return true; /* return label==this.label; */ } diff --git a/test/src/test/java/hudson/model/QueueTest.java b/test/src/test/java/hudson/model/QueueTest.java index 5e8d9eb2057b..24c75e5f760b 100644 --- a/test/src/test/java/hudson/model/QueueTest.java +++ b/test/src/test/java/hudson/model/QueueTest.java @@ -533,7 +533,7 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListen String tagName = queueItem.getDocumentElement().getTagName(); assertTrue(tagName.equals("blockedItem") || tagName.equals("buildableItem")); } - + @Issue("JENKINS-28926") @Test public void upstreamDownstreamCycle() throws Exception { @@ -833,32 +833,32 @@ public void run() { @Test public void testBlockBuildWhenUpstreamBuildingLock() throws Exception { final String prefix = "JENKINS-27871"; r.getInstance().setNumExecutors(4); - + final FreeStyleProject projectA = r.createFreeStyleProject(prefix+"A"); projectA.getBuildersList().add(new SleepBuilder(5000)); - + final FreeStyleProject projectB = r.createFreeStyleProject(prefix+"B"); - projectB.getBuildersList().add(new SleepBuilder(10000)); + projectB.getBuildersList().add(new SleepBuilder(10000)); projectB.setBlockBuildWhenUpstreamBuilding(true); final FreeStyleProject projectC = r.createFreeStyleProject(prefix+"C"); projectC.getBuildersList().add(new SleepBuilder(10000)); projectC.setBlockBuildWhenUpstreamBuilding(true); - + projectA.getPublishersList().add(new BuildTrigger(Collections.singletonList(projectB), Result.SUCCESS)); projectB.getPublishersList().add(new BuildTrigger(Collections.singletonList(projectC), Result.SUCCESS)); - + final QueueTaskFuture taskA = projectA.scheduleBuild2(0, new TimerTriggerCause()); Thread.sleep(1000); final QueueTaskFuture taskB = projectB.scheduleBuild2(0, new TimerTriggerCause()); final QueueTaskFuture taskC = projectC.scheduleBuild2(0, new TimerTriggerCause()); - - final FreeStyleBuild buildA = taskA.get(60, TimeUnit.SECONDS); - final FreeStyleBuild buildB = taskB.get(60, TimeUnit.SECONDS); + + final FreeStyleBuild buildA = taskA.get(60, TimeUnit.SECONDS); + final FreeStyleBuild buildB = taskB.get(60, TimeUnit.SECONDS); final FreeStyleBuild buildC = taskC.get(60, TimeUnit.SECONDS); long buildBEndTime = buildB.getStartTimeInMillis() + buildB.getDuration(); assertTrue("Project B build should be finished before the build of project C starts. " + - "B finished at " + buildBEndTime + ", C started at " + buildC.getStartTimeInMillis(), + "B finished at " + buildBEndTime + ", C started at " + buildC.getStartTimeInMillis(), buildC.getStartTimeInMillis() >= buildBEndTime); } diff --git a/test/src/test/java/hudson/model/RunParameterDefinitionTest.java b/test/src/test/java/hudson/model/RunParameterDefinitionTest.java index 869f98c054e7..f31f8cd66c57 100644 --- a/test/src/test/java/hudson/model/RunParameterDefinitionTest.java +++ b/test/src/test/java/hudson/model/RunParameterDefinitionTest.java @@ -101,13 +101,13 @@ public void testNULLFilter() throws Exception { project.getPublishersList().replaceBy(Collections.singleton(new ResultPublisher(Result.NOT_BUILT))); FreeStyleBuild notBuiltBuild = j.buildAndAssertStatus(Result.NOT_BUILT, project); - + project.getPublishersList().replaceBy(Collections.singleton(new ResultPublisher(Result.ABORTED))); FreeStyleBuild abortedBuild = j.buildAndAssertStatus(Result.ABORTED, project); FreeStyleProject paramProject = j.createFreeStyleProject("paramProject"); - ParametersDefinitionProperty pdp = - new ParametersDefinitionProperty(new RunParameterDefinition("RUN", + ParametersDefinitionProperty pdp = + new ParametersDefinitionProperty(new RunParameterDefinition("RUN", project.getName(), "run description", null)); @@ -118,7 +118,7 @@ public void testNULLFilter() throws Exception { build.getEnvironment(new LogTaskListener(LOGGER, Level.INFO)).get("RUN_NUMBER")); } - + @Test public void testALLFilter() throws Exception { @@ -133,13 +133,13 @@ public void testALLFilter() throws Exception { project.getPublishersList().replaceBy(Collections.singleton(new ResultPublisher(Result.NOT_BUILT))); FreeStyleBuild notBuiltBuild = j.buildAndAssertStatus(Result.NOT_BUILT, project); - + project.getPublishersList().replaceBy(Collections.singleton(new ResultPublisher(Result.ABORTED))); FreeStyleBuild abortedBuild = j.buildAndAssertStatus(Result.ABORTED, project); FreeStyleProject paramProject = j.createFreeStyleProject("paramProject"); - ParametersDefinitionProperty pdp = - new ParametersDefinitionProperty(new RunParameterDefinition("RUN", + ParametersDefinitionProperty pdp = + new ParametersDefinitionProperty(new RunParameterDefinition("RUN", project.getName(), "run description", RunParameterFilter.ALL)); @@ -164,13 +164,13 @@ public void testCOMPLETEDFilter() throws Exception { project.getPublishersList().replaceBy(Collections.singleton(new ResultPublisher(Result.NOT_BUILT))); FreeStyleBuild notBuiltBuild = j.buildAndAssertStatus(Result.NOT_BUILT, project); - + project.getPublishersList().replaceBy(Collections.singleton(new ResultPublisher(Result.ABORTED))); FreeStyleBuild abortedBuild = j.buildAndAssertStatus(Result.ABORTED, project); FreeStyleProject paramProject = j.createFreeStyleProject("paramProject"); - ParametersDefinitionProperty pdp = - new ParametersDefinitionProperty(new RunParameterDefinition("RUN", + ParametersDefinitionProperty pdp = + new ParametersDefinitionProperty(new RunParameterDefinition("RUN", project.getName(), "run description", RunParameterFilter.COMPLETED)); @@ -180,7 +180,7 @@ public void testCOMPLETEDFilter() throws Exception { assertEquals(Integer.toString(abortedBuild.getNumber()), build.getEnvironment(new LogTaskListener(LOGGER, Level.INFO)).get("RUN_NUMBER")); } - + @Test public void testSUCCESSFULFilter() throws Exception { @@ -195,13 +195,13 @@ public void testSUCCESSFULFilter() throws Exception { project.getPublishersList().replaceBy(Collections.singleton(new ResultPublisher(Result.NOT_BUILT))); FreeStyleBuild notBuiltBuild = j.buildAndAssertStatus(Result.NOT_BUILT, project); - + project.getPublishersList().replaceBy(Collections.singleton(new ResultPublisher(Result.ABORTED))); FreeStyleBuild abortedBuild = j.buildAndAssertStatus(Result.ABORTED, project); FreeStyleProject paramProject = j.createFreeStyleProject("paramProject"); - ParametersDefinitionProperty pdp = - new ParametersDefinitionProperty(new RunParameterDefinition("RUN", + ParametersDefinitionProperty pdp = + new ParametersDefinitionProperty(new RunParameterDefinition("RUN", project.getName(), "run description", RunParameterFilter.SUCCESSFUL)); @@ -211,8 +211,8 @@ public void testSUCCESSFULFilter() throws Exception { assertEquals(Integer.toString(unstableBuild.getNumber()), build.getEnvironment(new LogTaskListener(LOGGER, Level.INFO)).get("RUN_NUMBER")); } - - + + @Test public void testSTABLEFilter() throws Exception { @@ -227,13 +227,13 @@ public void testSTABLEFilter() throws Exception { project.getPublishersList().replaceBy(Collections.singleton(new ResultPublisher(Result.NOT_BUILT))); FreeStyleBuild notBuiltBuild = j.buildAndAssertStatus(Result.NOT_BUILT, project); - + project.getPublishersList().replaceBy(Collections.singleton(new ResultPublisher(Result.ABORTED))); FreeStyleBuild abortedBuild = j.buildAndAssertStatus(Result.ABORTED, project); FreeStyleProject paramProject = j.createFreeStyleProject("paramProject"); - ParametersDefinitionProperty pdp = - new ParametersDefinitionProperty(new RunParameterDefinition("RUN", + ParametersDefinitionProperty pdp = + new ParametersDefinitionProperty(new RunParameterDefinition("RUN", project.getName(), "run description", RunParameterFilter.STABLE)); @@ -243,8 +243,8 @@ public void testSTABLEFilter() throws Exception { assertEquals(Integer.toString(successfulBuild.getNumber()), build.getEnvironment(new LogTaskListener(LOGGER, Level.INFO)).get("RUN_NUMBER")); } - - + + @Test public void testLoadEnvironmentVariablesWhenRunParameterJobHasBeenDeleted() throws Exception { diff --git a/test/src/test/java/hudson/model/RunTest.java b/test/src/test/java/hudson/model/RunTest.java index 73e7c35c2d83..963dc80490bb 100644 --- a/test/src/test/java/hudson/model/RunTest.java +++ b/test/src/test/java/hudson/model/RunTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Jorg Heymans - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -217,7 +217,7 @@ public FullNameChangingProject newInstance(ItemGroup parent, String name) { } } } - + public static final class Mgr extends ArtifactManager { static final AtomicBoolean deleted = new AtomicBoolean(); @Override public boolean delete() { diff --git a/test/src/test/java/hudson/model/SimpleJobTest.java b/test/src/test/java/hudson/model/SimpleJobTest.java index e623b6111047..6b6f17ea77ec 100644 --- a/test/src/test/java/hudson/model/SimpleJobTest.java +++ b/test/src/test/java/hudson/model/SimpleJobTest.java @@ -18,20 +18,20 @@ public class SimpleJobTest { @Rule public JenkinsRule rule = new JenkinsRule(); - + @Test public void testGetEstimatedDuration() throws IOException { - + final SortedMap runs = new TreeMap<>(); - + Job project = createMockProject(runs); - + TestBuild previousPreviousBuild = new TestBuild(project, Result.SUCCESS, 20, null); runs.put(3, previousPreviousBuild); - + TestBuild previousBuild = new TestBuild(project, Result.SUCCESS, 15, previousPreviousBuild); runs.put(2, previousBuild); - + TestBuild lastBuild = new TestBuild(project, Result.SUCCESS, 42, previousBuild); runs.put(1, lastBuild); @@ -40,79 +40,79 @@ public void testGetEstimatedDuration() throws IOException { assertTrue("Expected < 42, but was "+project.getEstimatedDuration(), project.getEstimatedDuration() < 42); assertTrue("Expected > 15, but was "+project.getEstimatedDuration(), project.getEstimatedDuration() > 15); } - + @Test public void testGetEstimatedDurationWithOneRun() throws IOException { - + final SortedMap runs = new TreeMap<>(); - + Job project = createMockProject(runs); - + TestBuild lastBuild = new TestBuild(project, Result.SUCCESS, 42, null); runs.put(1, lastBuild); assertEquals(42, project.getEstimatedDuration()); } - + @Test public void testGetEstimatedDurationWithFailedRun() throws IOException { - + final SortedMap runs = new TreeMap<>(); - + Job project = createMockProject(runs); - + TestBuild lastBuild = new TestBuild(project, Result.FAILURE, 42, null); runs.put(1, lastBuild); assertEquals(42, project.getEstimatedDuration()); } - + @Test public void testGetEstimatedDurationWithNoRuns() { - + final SortedMap runs = new TreeMap<>(); - + Job project = createMockProject(runs); - + assertEquals(-1, project.getEstimatedDuration()); } - + @Test public void testGetEstimatedDurationIfPrevious3BuildsFailed() throws IOException { - + final SortedMap runs = new TreeMap<>(); - + Job project = createMockProject(runs); - + TestBuild prev5Build = new TestBuild(project, Result.UNSTABLE, 1, null); runs.put(6, prev5Build); - + TestBuild prev4Build = new TestBuild(project, Result.SUCCESS, 1, prev5Build); runs.put(5, prev4Build); - + TestBuild prev3Build = new TestBuild(project, Result.SUCCESS, 1, prev4Build); runs.put(4, prev3Build); - + TestBuild previous2Build = new TestBuild(project, Result.FAILURE, 50, prev3Build); runs.put(3, previous2Build); - + TestBuild previousBuild = new TestBuild(project, Result.FAILURE, 50, previous2Build); runs.put(2, previousBuild); - + TestBuild lastBuild = new TestBuild(project, Result.FAILURE, 50, previousBuild); runs.put(1, lastBuild); // failed builds must not be used, if there are successfulBuilds available. assertEquals(1, project.getEstimatedDuration()); } - + @Test public void testGetEstimatedDurationIfNoSuccessfulBuildTakeDurationOfFailedBuild() throws IOException { - + final SortedMap runs = new TreeMap<>(); - + Job project = createMockProject(runs); - + TestBuild lastBuild = new TestBuild(project, Result.FAILURE, 50, null); runs.put(1, lastBuild); @@ -125,29 +125,29 @@ private Job createMockProject(final SortedMap runs) { @SuppressWarnings("unchecked") private static class TestBuild extends Run { - + TestBuild(Job project, Result result, long duration, TestBuild previousBuild) throws IOException { super(project); this.result = result; this.duration = duration; this.previousBuild = previousBuild; } - + @Override public int compareTo(Run o) { return 0; } - + @Override public Result getResult() { return result; } - + @Override public boolean isBuilding() { return false; } - + } private class TestJob extends Job implements TopLevelItem { diff --git a/test/src/test/java/hudson/model/UpdateCenterCustomTest.java b/test/src/test/java/hudson/model/UpdateCenterCustomTest.java index 69d95d7f9469..a7af94a1fed8 100644 --- a/test/src/test/java/hudson/model/UpdateCenterCustomTest.java +++ b/test/src/test/java/hudson/model/UpdateCenterCustomTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2016 CloudBees, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -36,10 +36,10 @@ * Tests of the custom {@link UpdateCenter} implementation. */ public class UpdateCenterCustomTest { - + @Rule public final JenkinsRule j = new CustomUpdateCenterRule(CustomUpdateCenter.class); - + @Test public void shouldStartupWithCustomUpdateCenter() { UpdateCenter uc = j.jenkins.getUpdateCenter(); @@ -50,7 +50,7 @@ public void shouldStartupWithCustomUpdateCenter() { private static final class CustomUpdateCenterRule extends JenkinsRule { private final String updateCenterClassName; private String _oldValue = null; - + private static final String PROPERTY_NAME = UpdateCenter.class.getName()+".className"; CustomUpdateCenterRule(Class ucClass) { @@ -75,15 +75,15 @@ public String getUpdateCenterClassName() { return updateCenterClassName; } } - + public static final class CustomUpdateCenter extends UpdateCenter { public CustomUpdateCenter() { } - + public CustomUpdateCenter(UpdateCenterConfiguration config) { super(config); } - + } } diff --git a/test/src/test/java/hudson/model/UpdateCenterTest.java b/test/src/test/java/hudson/model/UpdateCenterTest.java index 630522f62d5a..142a5da6c1d7 100644 --- a/test/src/test/java/hudson/model/UpdateCenterTest.java +++ b/test/src/test/java/hudson/model/UpdateCenterTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -42,7 +42,7 @@ /** * Quick test for {@link UpdateCenter}. - * + * * @author Kohsuke Kawaguchi */ public class UpdateCenterTest { diff --git a/test/src/test/java/hudson/model/UpdateSiteTest.java b/test/src/test/java/hudson/model/UpdateSiteTest.java index 2928162f0e57..07d812102b3a 100644 --- a/test/src/test/java/hudson/model/UpdateSiteTest.java +++ b/test/src/test/java/hudson/model/UpdateSiteTest.java @@ -111,7 +111,7 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques public void shutdownWebserver() throws Exception { server.stop(); } - + @Test public void relativeURLs() throws Exception { URL url = new URL(baseUrl, "/plugins/htmlpublisher-update-center.json"); UpdateSite site = new UpdateSite(UpdateCenter.ID_DEFAULT, url.toString()); @@ -139,7 +139,7 @@ public void shutdownWebserver() throws Exception { UpdateSite site = getUpdateSite("/plugins/htmlpublisher-update-center.json"); UpdateSite alternativeSite = getUpdateSite("/plugins/alternative-update-center.json", "alternative"); overrideUpdateSite(site, alternativeSite); - // sites use different Wiki URL for dummy -> use URL from manifest + // sites use different Wiki URL for dummy -> use URL from manifest PluginWrapper wrapper = buildPluginWrapper("dummy", "https://wiki.jenkins.io/display/JENKINS/dummy"); assertEquals("https://wiki.jenkins.io/display/JENKINS/dummy", wrapper.getUrl()); // sites use the same Wiki URL for HTML Publisher -> use it diff --git a/test/src/test/java/hudson/model/UserTest.java b/test/src/test/java/hudson/model/UserTest.java index 390165df9e6b..e437ee05eff0 100644 --- a/test/src/test/java/hudson/model/UserTest.java +++ b/test/src/test/java/hudson/model/UserTest.java @@ -510,7 +510,7 @@ public void testCanDelete() throws IOException { // @Issue("SECURITY-180") public void security180() throws Exception { ApiTokenTestHelper.enableLegacyBehavior(); - + final GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); j.jenkins.setAuthorizationStrategy(auth); j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); diff --git a/test/src/test/java/hudson/model/ViewTest.java b/test/src/test/java/hudson/model/ViewTest.java index 82bc39c922a3..e2fee78121c1 100644 --- a/test/src/test/java/hudson/model/ViewTest.java +++ b/test/src/test/java/hudson/model/ViewTest.java @@ -982,7 +982,7 @@ public TopLevelItem newInstance(ItemGroup parent, String name) { } } - + //Duplication with ViewTest.CompositeView from core unit test module - unfortunately it is inaccessible from here private static class DummyCompositeView extends View implements ViewGroup { diff --git a/test/src/test/java/hudson/model/queue/BuildKeepsRunningWhenFaultySubTasksTest.java b/test/src/test/java/hudson/model/queue/BuildKeepsRunningWhenFaultySubTasksTest.java index 7c81f20bf976..b4140a41fa0d 100644 --- a/test/src/test/java/hudson/model/queue/BuildKeepsRunningWhenFaultySubTasksTest.java +++ b/test/src/test/java/hudson/model/queue/BuildKeepsRunningWhenFaultySubTasksTest.java @@ -24,7 +24,7 @@ public class BuildKeepsRunningWhenFaultySubTasksTest { public JenkinsRule j = new JenkinsRule(); public static final String ERROR_MESSAGE = "My unexpected exception"; - + // When using SubTaskContributor (FailingSubTaskContributor) the build never ends @Test @Issue("JENKINS-59793") @@ -36,7 +36,7 @@ public void buildFinishesWhenSubTaskFails() throws Exception { // We don't get stalled waiting the finalization of the job future.get(5, TimeUnit.SECONDS); } - + // A SubTask failing with an exception @TestExtension public static class FailingSubTaskContributor extends SubTaskContributor { diff --git a/test/src/test/java/hudson/node_monitors/ClockMonitorDescriptorTest.java b/test/src/test/java/hudson/node_monitors/ClockMonitorDescriptorTest.java index e84cbc3f048b..463b0c5d7188 100644 --- a/test/src/test/java/hudson/node_monitors/ClockMonitorDescriptorTest.java +++ b/test/src/test/java/hudson/node_monitors/ClockMonitorDescriptorTest.java @@ -16,10 +16,10 @@ * @author Richard Mortimer */ public class ClockMonitorDescriptorTest { - + @Rule public JenkinsRule jenkins = new JenkinsRule(); - + /** * Makes sure that it returns sensible values. */ diff --git a/test/src/test/java/hudson/pages/SystemConfigurationTestCase.java b/test/src/test/java/hudson/pages/SystemConfigurationTestCase.java index 1bc4d88558f2..8f8cee86a602 100644 --- a/test/src/test/java/hudson/pages/SystemConfigurationTestCase.java +++ b/test/src/test/java/hudson/pages/SystemConfigurationTestCase.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Erik Ramfelt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/test/src/test/java/hudson/scm/AbstractScmTagActionTest.java b/test/src/test/java/hudson/scm/AbstractScmTagActionTest.java index df6a146f48c6..cc53fe3aada1 100644 --- a/test/src/test/java/hudson/scm/AbstractScmTagActionTest.java +++ b/test/src/test/java/hudson/scm/AbstractScmTagActionTest.java @@ -55,7 +55,7 @@ public class AbstractScmTagActionTest { @Test public void regularTextDisplayedCorrectly() throws Exception { FreeStyleProject p = j.createFreeStyleProject(); - + String tagToKeep = "Nice tag with space"; p.setScm(new FakeSCM(tagToKeep)); @@ -64,7 +64,7 @@ public void regularTextDisplayedCorrectly() throws Exception { String tooltip = buildAndExtractTooltipAttribute(p); assertEquals(tagToKeep, tooltip); } - + @Test @Issue("SECURITY-1537") public void preventXssInTagAction() throws Exception { @@ -77,7 +77,7 @@ public void preventXssInTagAction() throws Exception { assertThat(tooltip, not(containsString("<"))); assertThat(tooltip, startsWith("<")); } - + private String buildAndExtractTooltipAttribute(FreeStyleProject p) throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); diff --git a/test/src/test/java/hudson/scm/ScmTest.java b/test/src/test/java/hudson/scm/ScmTest.java index bd683c8d5541..a69709dee40a 100644 --- a/test/src/test/java/hudson/scm/ScmTest.java +++ b/test/src/test/java/hudson/scm/ScmTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/test/src/test/java/hudson/search/SearchTest.java b/test/src/test/java/hudson/search/SearchTest.java index 5250cd489313..ac1fd2390047 100644 --- a/test/src/test/java/hudson/search/SearchTest.java +++ b/test/src/test/java/hudson/search/SearchTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -59,9 +59,9 @@ * @author Kohsuke Kawaguchi */ public class SearchTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + /** * No exact match should result in a failure status code. */ @@ -87,17 +87,17 @@ public void testXSS() throws Exception { HtmlPage resultPage = wc.search(""); assertEquals(HttpURLConnection.HTTP_NOT_FOUND, resultPage.getWebResponse().getStatusCode()); } - + @Test public void testSearchByProjectName() throws Exception { final String projectName = "testSearchByProjectName"; - + j.createFreeStyleProject(projectName); - + Page result = j.search(projectName); assertNotNull(result); j.assertGoodStatus(result); - + // make sure we've fetched the testSearchByDisplayName project page String contents = result.getWebResponse().getContentAsString(); assertTrue(contents.contains(String.format("%s [Jenkins]", projectName))); @@ -137,19 +137,19 @@ public void testSearchByProjectNameInAFolder() throws Exception { @Test public void testSearchByDisplayName() throws Exception { final String displayName = "displayName9999999"; - + FreeStyleProject project = j.createFreeStyleProject("testSearchByDisplayName"); project.setDisplayName(displayName); - + Page result = j.search(displayName); assertNotNull(result); j.assertGoodStatus(result); - + // make sure we've fetched the testSearchByDisplayName project page String contents = result.getWebResponse().getContentAsString(); assertTrue(contents.contains(String.format("%s [Jenkins]", displayName))); } - + @Test public void testSearch2ProjectsWithSameDisplayName() throws Exception { // create 2 freestyle projects with the same display name @@ -158,7 +158,7 @@ public void testSearch2ProjectsWithSameDisplayName() throws Exception { final String projectName3 = "projectName3"; final String displayName = "displayNameFoo"; final String otherDisplayName = "otherDisplayName"; - + FreeStyleProject project1 = j.createFreeStyleProject(projectName1); project1.setDisplayName(displayName); FreeStyleProject project2 = j.createFreeStyleProject(projectName2); @@ -178,7 +178,7 @@ public void testSearch2ProjectsWithSameDisplayName() throws Exception { assertTrue(contents.contains(String.format("%s [Jenkins]", displayName))); assertFalse(contents.contains(otherDisplayName)); } - + @Test public void testProjectNamePrecedesDisplayName() throws Exception { final String project1Name = "foo"; @@ -187,11 +187,11 @@ public void testProjectNamePrecedesDisplayName() throws Exception { final String project2DisplayName = project1Name; final String project3Name = "project3Name"; final String project3DisplayName = "project3DisplayName"; - + // create 1 freestyle project with the name foo FreeStyleProject project1 = j.createFreeStyleProject(project1Name); project1.setDisplayName(project1DisplayName); - + // create another with the display name foo FreeStyleProject project2 = j.createFreeStyleProject(project2Name); project2.setDisplayName(project2DisplayName); @@ -199,12 +199,12 @@ public void testProjectNamePrecedesDisplayName() throws Exception { // create a third project and make sure it's not picked up by search FreeStyleProject project3 = j.createFreeStyleProject(project3Name); project3.setDisplayName(project3DisplayName); - + // search for foo Page result = j.search(project1Name); assertNotNull(result); j.assertGoodStatus(result); - + // make sure we get the project with the name foo String contents = result.getWebResponse().getContentAsString(); assertTrue(contents.contains(String.format("%s [Jenkins]", project1DisplayName))); @@ -213,7 +213,7 @@ public void testProjectNamePrecedesDisplayName() throws Exception { assertFalse(contents.contains(project3Name)); assertFalse(contents.contains(project3DisplayName)); } - + @Test public void testGetSuggestionsHasBothNamesAndDisplayNames() throws Exception { final String projectName = "project name"; @@ -221,26 +221,26 @@ public void testGetSuggestionsHasBothNamesAndDisplayNames() throws Exception { FreeStyleProject project1 = j.createFreeStyleProject(projectName); project1.setDisplayName(displayName); - + WebClient wc = j.createWebClient(); Page result = wc.goTo("search/suggest?query=name", "application/json"); assertNotNull(result); j.assertGoodStatus(result); - + String content = result.getWebResponse().getContentAsString(); System.out.println(content); JSONObject jsonContent = (JSONObject)JSONSerializer.toJSON(content); assertNotNull(jsonContent); JSONArray jsonArray = jsonContent.getJSONArray("suggestions"); assertNotNull(jsonArray); - + assertEquals(2, jsonArray.size()); - + boolean foundProjectName = false; boolean foundDisplayName = false; for(Object suggestion : jsonArray) { JSONObject jsonSuggestion = (JSONObject)suggestion; - + String name = (String)jsonSuggestion.get("name"); if(projectName.equals(name)) { foundProjectName = true; @@ -405,7 +405,7 @@ public void run() { } }); } - + @Test public void testSearchWithinFolders() throws Exception { MockFolder folder1 = j.createFolder("folder1"); diff --git a/test/src/test/java/hudson/security/ExtendedReadPermissionTest.java b/test/src/test/java/hudson/security/ExtendedReadPermissionTest.java index 5a3b154a7f39..515c704f1cb4 100644 --- a/test/src/test/java/hudson/security/ExtendedReadPermissionTest.java +++ b/test/src/test/java/hudson/security/ExtendedReadPermissionTest.java @@ -68,7 +68,7 @@ private void setPermissionEnabled(boolean enabled) { + " MockAuthorizationStrategy does not implement this check.") @Test public void readOnlyConfigAccessWithPermissionDisabled() throws Exception { setPermissionEnabled(false); - + JenkinsRule.WebClient wc = r.createWebClient(); wc.withBasicCredentials("charlie"); diff --git a/test/src/test/java/hudson/security/HudsonPrivateSecurityRealmTest.java b/test/src/test/java/hudson/security/HudsonPrivateSecurityRealmTest.java index 4ba76a0dedb8..80f6c4ec1f66 100644 --- a/test/src/test/java/hudson/security/HudsonPrivateSecurityRealmTest.java +++ b/test/src/test/java/hudson/security/HudsonPrivateSecurityRealmTest.java @@ -98,7 +98,7 @@ public void setup() throws Exception { public void fullNameCollisionPassword() throws Exception { HudsonPrivateSecurityRealm securityRealm = new HudsonPrivateSecurityRealm(false, false, null); j.jenkins.setSecurityRealm(securityRealm); - + User u1 = securityRealm.createAccount("user1", "password1"); u1.setFullName("User One"); u1.save(); @@ -113,17 +113,17 @@ public void fullNameCollisionPassword() throws Exception { WebClient wc2 = j.createWebClient(); wc2.login("user2", "password2"); - + // Check both users can use their token XmlPage w1 = (XmlPage) wc1.goTo("whoAmI/api/xml", "application/xml"); assertThat(w1, hasXPath("//name", is("user1"))); - + XmlPage w2 = (XmlPage) wc2.goTo("whoAmI/api/xml", "application/xml"); assertThat(w2, hasXPath("//name", is("user2"))); u1.setFullName("user2"); u1.save(); - + // check the tokens still work wc1 = j.createWebClient(); wc1.login("user1", "password1"); @@ -135,7 +135,7 @@ public void fullNameCollisionPassword() throws Exception { // belt and braces in case the failed login no longer throws exceptions. w1 = (XmlPage) wc1.goTo("whoAmI/api/xml", "application/xml"); assertThat(w1, hasXPath("//name", is("user1"))); - + w2 = (XmlPage) wc2.goTo("whoAmI/api/xml", "application/xml"); assertThat(w2, hasXPath("//name", is("user2"))); } @@ -144,10 +144,10 @@ public void fullNameCollisionPassword() throws Exception { @Test public void fullNameCollisionToken() throws Exception { ApiTokenTestHelper.enableLegacyBehavior(); - + HudsonPrivateSecurityRealm securityRealm = new HudsonPrivateSecurityRealm(false, false, null); j.jenkins.setSecurityRealm(securityRealm); - + User u1 = securityRealm.createAccount("user1", "password1"); u1.setFullName("User One"); u1.save(); @@ -165,11 +165,11 @@ public void fullNameCollisionToken() throws Exception { WebClient wc2 = j.createWebClient(); wc2.addRequestHeader("Authorization", basicHeader("user2", u2Token)); //wc2.setCredentialsProvider(new FixedCredentialsProvider("user2", u1Token)); - + // Check both users can use their token XmlPage w1 = (XmlPage) wc1.goTo("whoAmI/api/xml", "application/xml"); assertThat(w1, hasXPath("//name", is("user1"))); - + XmlPage w2 = (XmlPage) wc2.goTo("whoAmI/api/xml", "application/xml"); assertThat(w2, hasXPath("//name", is("user2"))); @@ -179,7 +179,7 @@ public void fullNameCollisionToken() throws Exception { // check the tokens still work w1 = (XmlPage) wc1.goTo("whoAmI/api/xml", "application/xml"); assertThat(w1, hasXPath("//name", is("user1"))); - + w2 = (XmlPage) wc2.goTo("whoAmI/api/xml", "application/xml"); assertThat(w2, hasXPath("//name", is("user2"))); } @@ -424,11 +424,11 @@ protected void loggedIn(@NonNull String username) { public void controlCharacterAreNoMoreValid() throws Exception { HudsonPrivateSecurityRealm securityRealm = new HudsonPrivateSecurityRealm(true, false, null); j.jenkins.setSecurityRealm(securityRealm); - + String password = "testPwd"; String email = "test@test.com"; int i = 0; - + // regular case = only accepting a-zA-Z0-9 + "-_" checkUserCanBeCreatedWith(securityRealm, "test" + i, password, "Test" + i, email); assertNotNull(User.getById("test" + i, false)); @@ -454,23 +454,23 @@ public void controlCharacterAreNoMoreValid() throws Exception { checkUserCannotBeCreatedWith(securityRealm, "te\u0000st" + i, password, "Test" + i, email); } } - + @Issue("SECURITY-786") @Test public void controlCharacterAreNoMoreValid_CustomRegex() throws Exception { HudsonPrivateSecurityRealm securityRealm = new HudsonPrivateSecurityRealm(true, false, null); j.jenkins.setSecurityRealm(securityRealm); - + String currentRegex = "^[A-Z]+[0-9]*$"; - + Field field = HudsonPrivateSecurityRealm.class.getDeclaredField("ID_REGEX"); field.setAccessible(true); field.set(null, currentRegex); - + String password = "testPwd"; String email = "test@test.com"; int i = 0; - + // regular case = only accepting a-zA-Z0-9 + "-_" checkUserCanBeCreatedWith(securityRealm, "TEST" + i, password, "Test" + i, email); assertNotNull(User.getById("TEST" + i, false)); @@ -489,7 +489,7 @@ public void controlCharacterAreNoMoreValid_CustomRegex() throws Exception { { // we can even change regex on the fly currentRegex = "^[0-9]*$"; field.set(null, currentRegex); - + checkUserCanBeCreatedWith(securityRealm, "125213" + i, password, "Test" + i, email); assertNotNull(User.getById("125213" + i, false)); i++; @@ -557,7 +557,7 @@ public void ensureHashingVersion_2x_isNotSupported() { public void ensureHashingVersion_2y_isNotSupported() { assertThrows(IllegalArgumentException.class, () -> BCrypt.checkpw("a", "$2y$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V.")); } - + private void checkUserCanBeCreatedWith(HudsonPrivateSecurityRealm securityRealm, String id, String password, String fullName, String email) throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); SignupPage signup = new SignupPage(wc.goTo("signup")); @@ -568,7 +568,7 @@ private void checkUserCanBeCreatedWith(HudsonPrivateSecurityRealm securityRealm, HtmlPage success = signup.submit(j); assertThat(success.getElementById("main-panel").getTextContent(), containsString("Success")); } - + private void checkUserCannotBeCreatedWith(HudsonPrivateSecurityRealm securityRealm, String id, String password, String fullName, String email) throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); SignupPage signup = new SignupPage(wc.goTo("signup")); @@ -580,7 +580,7 @@ private void checkUserCannotBeCreatedWith(HudsonPrivateSecurityRealm securityRea assertThat(success.getElementById("main-panel").getTextContent(), not(containsString("Success"))); assertThat(success.getElementById("main-panel").getTextContent(), containsString(Messages.HudsonPrivateSecurityRealm_CreateAccount_UserNameInvalidCharacters())); } - + private void checkUserCannotBeCreatedWith_custom(HudsonPrivateSecurityRealm securityRealm, String id, String password, String fullName, String email, String regex) throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); SignupPage signup = new SignupPage(wc.goTo("signup")); diff --git a/test/src/test/java/hudson/security/PermissionGroupTest.java b/test/src/test/java/hudson/security/PermissionGroupTest.java index 70d87fa57827..f6fd5d693bac 100644 --- a/test/src/test/java/hudson/security/PermissionGroupTest.java +++ b/test/src/test/java/hudson/security/PermissionGroupTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/test/src/test/java/hudson/security/WhoAmITest.java b/test/src/test/java/hudson/security/WhoAmITest.java index dae0f6940ac4..39c8517a41b0 100644 --- a/test/src/test/java/hudson/security/WhoAmITest.java +++ b/test/src/test/java/hudson/security/WhoAmITest.java @@ -79,7 +79,7 @@ public void whoAmI_regular_doesNotProvideSensitiveInformation() throws Exception assertThat(sessionId, not(nullValue())); - // dangerous stuff in Regular Login mode: + // dangerous stuff in Regular Login mode: /* * Details: * org.acegisecurity.ui.WebAuthenticationDetails@12afc: RemoteIpAddress: 127.0.0.1; SessionId: node0gbmv9ly0f3h517eppoupykq6n0 @@ -120,7 +120,7 @@ public void whoAmI_regularApi_doesNotProvideSensitiveInformation() throws Except assertThat(sessionId, not(nullValue())); - // dangerous stuff in Regular Login mode with the api/json call: + // dangerous stuff in Regular Login mode with the api/json call: /* * { * "_class": "hudson.security.WhoAmI", @@ -156,7 +156,7 @@ public void whoAmI_basic_doesNotProvideSensitiveInformation() throws Exception { HtmlPage whoAmIPage = wc.goTo("whoAmI"); String content = whoAmIPage.getWebResponse().getContentAsString(); - // dangerous stuff in Basic mode: + // dangerous stuff in Basic mode: /* * toString: * org.acegisecurity.providers.UsernamePasswordAuthenticationToken@e8fd00a7: Username: [toString()=S3cr3t]; @@ -191,7 +191,7 @@ public void whoAmI_apiToken_doesNotProvideSensitiveInformation() throws Exceptio HtmlPage whoAmIPage = wc.goTo("whoAmI"); String content = whoAmIPage.getWebResponse().getContentAsString(); - // dangerous stuff in API Token mode: + // dangerous stuff in API Token mode: /* * Authorization * Basic dXNlcjoxMTRiNGRmMWNhZTVkNDQ2MjgxZTJkZWEzMDY1NTEyZDBi diff --git a/test/src/test/java/hudson/security/csrf/DefaultCrumbIssuerTest.java b/test/src/test/java/hudson/security/csrf/DefaultCrumbIssuerTest.java index f86ee94a288a..84cb77b17c94 100644 --- a/test/src/test/java/hudson/security/csrf/DefaultCrumbIssuerTest.java +++ b/test/src/test/java/hudson/security/csrf/DefaultCrumbIssuerTest.java @@ -42,7 +42,7 @@ * @author dty */ public class DefaultCrumbIssuerTest { - + @Rule public JenkinsRule r = new JenkinsRule(); @Before public void setIssuer() { @@ -74,7 +74,7 @@ public class DefaultCrumbIssuerTest { HtmlPage p = wc.goTo("configure"); wc.removeRequestHeader(HEADER_NAME); - + wc.setThrowExceptionOnFailingStatusCode(false); // The crumb should no longer match if we remove the proxy info Page page = r.submit(p.getFormByName("config")); @@ -156,7 +156,7 @@ public class DefaultCrumbIssuerTest { .withThrowExceptionOnFailingStatusCode(false); Page page = wc.goTo("quietDown"); - assertEquals("expect HTTP 405 method not allowed", + assertEquals("expect HTTP 405 method not allowed", HttpURLConnection.HTTP_BAD_METHOD, page.getWebResponse().getStatusCode()); diff --git a/test/src/test/java/hudson/slaves/EnvironmentVariableNodePropertyTest.java b/test/src/test/java/hudson/slaves/EnvironmentVariableNodePropertyTest.java index e13958293547..93edbc76b041 100644 --- a/test/src/test/java/hudson/slaves/EnvironmentVariableNodePropertyTest.java +++ b/test/src/test/java/hudson/slaves/EnvironmentVariableNodePropertyTest.java @@ -29,147 +29,147 @@ */ public class EnvironmentVariableNodePropertyTest { - @ClassRule - public static BuildWatcher buildWatcher = new BuildWatcher(); - - @Rule - public JenkinsRule j = new JenkinsRule(); - - private DumbSlave agent; - private FreeStyleProject project; - - /** - * Agent properties are available - */ - @Test - public void testAgentPropertyOnAgent() throws Exception { - setVariables(agent, new EnvironmentVariablesNodeProperty.Entry("KEY", "agentValue")); - Map envVars = executeBuild(agent); - assertEquals("agentValue", envVars.get("KEY")); - } - - /** - * Built-in node properties are available - */ - @Test - public void testControllerPropertyOnBuiltInNode() throws Exception { + @ClassRule + public static BuildWatcher buildWatcher = new BuildWatcher(); + + @Rule + public JenkinsRule j = new JenkinsRule(); + + private DumbSlave agent; + private FreeStyleProject project; + + /** + * Agent properties are available + */ + @Test + public void testAgentPropertyOnAgent() throws Exception { + setVariables(agent, new EnvironmentVariablesNodeProperty.Entry("KEY", "agentValue")); + Map envVars = executeBuild(agent); + assertEquals("agentValue", envVars.get("KEY")); + } + + /** + * Built-in node properties are available + */ + @Test + public void testControllerPropertyOnBuiltInNode() throws Exception { j.jenkins.getGlobalNodeProperties().replaceBy( Collections.singleton(new EnvironmentVariablesNodeProperty( new EnvironmentVariablesNodeProperty.Entry("KEY", "globalValue")))); - Map envVars = executeBuild(j.jenkins); + Map envVars = executeBuild(j.jenkins); - assertEquals("globalValue", envVars.get("KEY")); - } + assertEquals("globalValue", envVars.get("KEY")); + } - /** - * Both agent and controller properties are available, but agent properties have priority - */ - @Test - public void testAgentAndControllerPropertyOnAgent() throws Exception { + /** + * Both agent and controller properties are available, but agent properties have priority + */ + @Test + public void testAgentAndControllerPropertyOnAgent() throws Exception { j.jenkins.getGlobalNodeProperties().replaceBy( Collections.singleton(new EnvironmentVariablesNodeProperty( new EnvironmentVariablesNodeProperty.Entry("KEY", "globalValue")))); - setVariables(agent, new EnvironmentVariablesNodeProperty.Entry("KEY", "agentValue")); - - Map envVars = executeBuild(agent); - - assertEquals("agentValue", envVars.get("KEY")); - } - - /** - * Agent and controller properties and parameters are available. - * Priority: parameters > agent > controller - */ - @Test - // TODO(terminology) is this correct? This sets a built-in node property, not a global property - public void testAgentAndBuiltInNodePropertyAndParameterOnAgent() - throws Exception { - ParametersDefinitionProperty pdp = new ParametersDefinitionProperty( - new StringParameterDefinition("KEY", "parameterValue")); - project.addProperty(pdp); - - setVariables(j.jenkins, new EnvironmentVariablesNodeProperty.Entry("KEY", "builtInNodeValue")); - setVariables(agent, new EnvironmentVariablesNodeProperty.Entry("KEY", "agentValue")); - - Map envVars = executeBuild(agent); - - assertEquals("parameterValue", envVars.get("KEY")); - } - - @Test - public void testVariableResolving() throws Exception { + setVariables(agent, new EnvironmentVariablesNodeProperty.Entry("KEY", "agentValue")); + + Map envVars = executeBuild(agent); + + assertEquals("agentValue", envVars.get("KEY")); + } + + /** + * Agent and controller properties and parameters are available. + * Priority: parameters > agent > controller + */ + @Test + // TODO(terminology) is this correct? This sets a built-in node property, not a global property + public void testAgentAndBuiltInNodePropertyAndParameterOnAgent() + throws Exception { + ParametersDefinitionProperty pdp = new ParametersDefinitionProperty( + new StringParameterDefinition("KEY", "parameterValue")); + project.addProperty(pdp); + + setVariables(j.jenkins, new EnvironmentVariablesNodeProperty.Entry("KEY", "builtInNodeValue")); + setVariables(agent, new EnvironmentVariablesNodeProperty.Entry("KEY", "agentValue")); + + Map envVars = executeBuild(agent); + + assertEquals("parameterValue", envVars.get("KEY")); + } + + @Test + public void testVariableResolving() throws Exception { j.jenkins.getGlobalNodeProperties().replaceBy( Collections.singleton(new EnvironmentVariablesNodeProperty( new EnvironmentVariablesNodeProperty.Entry("KEY1", "value"), new EnvironmentVariablesNodeProperty.Entry("KEY2", "$KEY1")))); - Map envVars = executeBuild(j.jenkins); - assertEquals("value", envVars.get("KEY1")); - assertEquals("value", envVars.get("KEY2")); - } - - @Test - public void testFormRoundTripForController() throws Exception { + Map envVars = executeBuild(j.jenkins); + assertEquals("value", envVars.get("KEY1")); + assertEquals("value", envVars.get("KEY2")); + } + + @Test + public void testFormRoundTripForController() throws Exception { j.jenkins.getGlobalNodeProperties().replaceBy( Collections.singleton(new EnvironmentVariablesNodeProperty( new EnvironmentVariablesNodeProperty.Entry("KEY", "value")))); - - WebClient webClient = j.createWebClient(); - HtmlPage page = webClient.getPage(j.jenkins, "configure"); - HtmlForm form = page.getFormByName("config"); - j.submit(form); - - assertEquals(1, j.jenkins.getGlobalNodeProperties().toList().size()); - - EnvironmentVariablesNodeProperty prop = j.jenkins.getGlobalNodeProperties().get(EnvironmentVariablesNodeProperty.class); - assertEquals(1, prop.getEnvVars().size()); - assertEquals("value", prop.getEnvVars().get("KEY")); - } - - @Test - public void testFormRoundTripForAgent() throws Exception { - setVariables(agent, new EnvironmentVariablesNodeProperty.Entry("KEY", "value")); - - WebClient webClient = j.createWebClient(); - HtmlPage page = webClient.getPage(agent, "configure"); - HtmlForm form = page.getFormByName("config"); - j.submit(form); - - assertEquals(1, agent.getNodeProperties().toList().size()); - - EnvironmentVariablesNodeProperty prop = agent.getNodeProperties().get(EnvironmentVariablesNodeProperty.class); - assertEquals(1, prop.getEnvVars().size()); - assertEquals("value", prop.getEnvVars().get("KEY")); - } - - // //////////////////////// setup ////////////////////////////////////////// - - @Before - public void setUp() throws Exception { - agent = j.createSlave(); - project = j.createFreeStyleProject(); - } - - // ////////////////////// helper methods ///////////////////////////////// - - private void setVariables(Node node, EnvironmentVariablesNodeProperty.Entry... entries) throws IOException { - node.getNodeProperties().replaceBy( - Collections.singleton(new EnvironmentVariablesNodeProperty( - entries))); - - } - - /** - * Launches project on this node, waits for the result, and returns the environment that is used - */ - private Map executeBuild(Node node) throws Exception { - CaptureEnvironmentBuilder builder = new CaptureEnvironmentBuilder(); - - project.getBuildersList().add(builder); - project.setAssignedLabel(node.getSelfLabel()); - - FreeStyleBuild build = j.buildAndAssertSuccess(project); - - return builder.getEnvVars(); - } + + WebClient webClient = j.createWebClient(); + HtmlPage page = webClient.getPage(j.jenkins, "configure"); + HtmlForm form = page.getFormByName("config"); + j.submit(form); + + assertEquals(1, j.jenkins.getGlobalNodeProperties().toList().size()); + + EnvironmentVariablesNodeProperty prop = j.jenkins.getGlobalNodeProperties().get(EnvironmentVariablesNodeProperty.class); + assertEquals(1, prop.getEnvVars().size()); + assertEquals("value", prop.getEnvVars().get("KEY")); + } + + @Test + public void testFormRoundTripForAgent() throws Exception { + setVariables(agent, new EnvironmentVariablesNodeProperty.Entry("KEY", "value")); + + WebClient webClient = j.createWebClient(); + HtmlPage page = webClient.getPage(agent, "configure"); + HtmlForm form = page.getFormByName("config"); + j.submit(form); + + assertEquals(1, agent.getNodeProperties().toList().size()); + + EnvironmentVariablesNodeProperty prop = agent.getNodeProperties().get(EnvironmentVariablesNodeProperty.class); + assertEquals(1, prop.getEnvVars().size()); + assertEquals("value", prop.getEnvVars().get("KEY")); + } + + // //////////////////////// setup ////////////////////////////////////////// + + @Before + public void setUp() throws Exception { + agent = j.createSlave(); + project = j.createFreeStyleProject(); + } + + // ////////////////////// helper methods ///////////////////////////////// + + private void setVariables(Node node, EnvironmentVariablesNodeProperty.Entry... entries) throws IOException { + node.getNodeProperties().replaceBy( + Collections.singleton(new EnvironmentVariablesNodeProperty( + entries))); + + } + + /** + * Launches project on this node, waits for the result, and returns the environment that is used + */ + private Map executeBuild(Node node) throws Exception { + CaptureEnvironmentBuilder builder = new CaptureEnvironmentBuilder(); + + project.getBuildersList().add(builder); + project.setAssignedLabel(node.getSelfLabel()); + + FreeStyleBuild build = j.buildAndAssertSuccess(project); + + return builder.getEnvVars(); + } } diff --git a/test/src/test/java/hudson/slaves/JNLPLauncherTest.java b/test/src/test/java/hudson/slaves/JNLPLauncherTest.java index 81ce8c714a77..23247fd5d7a3 100644 --- a/test/src/test/java/hudson/slaves/JNLPLauncherTest.java +++ b/test/src/test/java/hudson/slaves/JNLPLauncherTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -69,13 +69,13 @@ @Category(SmokeTest.class) public class JNLPLauncherTest { @Rule public JenkinsRule j = new JenkinsRule(); - + @Rule public TemporaryFolder tmpDir = new TemporaryFolder(); @Rule public LoggerRule logging = new LoggerRule().record(Slave.class, Level.FINE); /** - * Starts a JNLP agent and makes sure it successfully connects to Jenkins. + * Starts a JNLP agent and makes sure it successfully connects to Jenkins. */ @Test public void testLaunch() throws Exception { @@ -84,16 +84,16 @@ public void testLaunch() throws Exception { Computer c = addTestAgent(false); launchJnlpAndVerify(c, buildJnlpArgs(c)); } - + /** - * Starts a JNLP agent and makes sure it successfully connects to Jenkins. + * Starts a JNLP agent and makes sure it successfully connects to Jenkins. */ @Test @Issue("JENKINS-39370") public void testLaunchWithWorkDir() throws Exception { Assume.assumeFalse("Skipping JNLPLauncherTest.testLaunch because we are running headless", GraphicsEnvironment.isHeadless()); File workDir = tmpDir.newFolder("workDir"); - + Computer c = addTestAgent(false); launchJnlpAndVerify(c, buildJnlpArgs(c).add("-workDir", workDir.getAbsolutePath())); assertTrue("Remoting work dir should have been created", new File(workDir, "remoting").exists()); @@ -110,45 +110,45 @@ public void testHeadlessLaunch() throws Exception { // make sure that onOffline gets called just the right number of times assertEquals(1, ComputerListener.all().get(ListenerImpl.class).offlined); } - + @Test @Issue("JENKINS-44112") public void testHeadlessLaunchWithWorkDir() throws Exception { Assume.assumeFalse("Skipping JNLPLauncherTest.testLaunch because we are running headless", GraphicsEnvironment.isHeadless()); - + Computer c = addTestAgent(true); launchJnlpAndVerify(c, buildJnlpArgs(c).add("-arg","-headless")); assertEquals(1, ComputerListener.all().get(ListenerImpl.class).offlined); } - + @Test @Issue("JENKINS-39370") public void testHeadlessLaunchWithCustomWorkDir() throws Exception { Assume.assumeFalse("Skipping JNLPLauncherTest.testLaunch because we are running headless", GraphicsEnvironment.isHeadless()); File workDir = tmpDir.newFolder("workDir"); - + Computer c = addTestAgent(false); launchJnlpAndVerify(c, buildJnlpArgs(c).add("-arg","-headless", "-workDir", workDir.getAbsolutePath())); assertEquals(1, ComputerListener.all().get(ListenerImpl.class).offlined); } - + @Test @LocalData @Issue("JENKINS-44112") public void testNoWorkDirMigration() { Computer computer = j.jenkins.getComputer("Foo"); assertThat(computer, instanceOf(SlaveComputer.class)); - + SlaveComputer c = (SlaveComputer)computer; ComputerLauncher launcher = c.getLauncher(); assertThat(launcher, instanceOf(JNLPLauncher.class)); JNLPLauncher jnlpLauncher = (JNLPLauncher)launcher; - assertNotNull("Work Dir Settings should be defined", + assertNotNull("Work Dir Settings should be defined", jnlpLauncher.getWorkDirSettings()); - assertTrue("Work directory should be disabled for the migrated agent", + assertTrue("Work directory should be disabled for the migrated agent", jnlpLauncher.getWorkDirSettings().isDisabled()); } - + @Test @Issue("JENKINS-44112") @SuppressWarnings("deprecation") @@ -212,7 +212,7 @@ private ArgumentListBuilder buildJnlpArgs(Computer c) throws Exception { args.add("-headless","-basedir"); args.add(j.createTmpDir()); args.add("-nosecurity","-jnlp", j.getURL() + "computer/"+c.getName()+"/jenkins-agent.jnlp"); - + if (c instanceof SlaveComputer) { SlaveComputer sc = (SlaveComputer)c; ComputerLauncher launcher = sc.getLauncher(); @@ -220,7 +220,7 @@ private ArgumentListBuilder buildJnlpArgs(Computer c) throws Exception { args.add(((JNLPLauncher)launcher).getWorkDirSettings().toCommandLineArgs(sc)); } } - + return args; } diff --git a/test/src/test/java/hudson/slaves/NodeProvisionerTest.java b/test/src/test/java/hudson/slaves/NodeProvisionerTest.java index 6d2c89daa934..a7c6552cda90 100644 --- a/test/src/test/java/hudson/slaves/NodeProvisionerTest.java +++ b/test/src/test/java/hudson/slaves/NodeProvisionerTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/test/src/test/java/hudson/tasks/FingerprinterTest.java b/test/src/test/java/hudson/tasks/FingerprinterTest.java index 5ca37997667e..62f56033acf6 100644 --- a/test/src/test/java/hudson/tasks/FingerprinterTest.java +++ b/test/src/test/java/hudson/tasks/FingerprinterTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright 2011 Yahoo!, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -90,7 +90,7 @@ public class FingerprinterTest { "test.txt", "test2.txt", }; - + private static final String renamedProject1 = "renamed project 1"; private static final String renamedProject2 = "renamed project 2"; @@ -100,7 +100,7 @@ public class FingerprinterTest { public static void setUp() { Fingerprinter.enableFingerprintsInDependencyGraph = true; } - + @Test public void fingerprintDependencies() throws Exception { FreeStyleProject upstream = createFreeStyleProjectWithFingerprints(singleContents, singleFiles); FreeStyleProject downstream = createFreeStyleProjectWithFingerprints(singleContents, singleFiles); @@ -206,19 +206,19 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListen @Test public void circularDependency() throws Exception { FreeStyleProject p = createFreeStyleProjectWithFingerprints(singleContents, singleFiles); - + j.buildAndAssertSuccess(p); j.buildAndAssertSuccess(p); - + Jenkins.get().rebuildDependencyGraph(); List upstreamProjects = p.getUpstreamProjects(); List downstreamProjects = p.getDownstreamProjects(); - + assertEquals(0, upstreamProjects.size()); assertEquals(0, downstreamProjects.size()); } - + @Test public void matrixDependency() throws Exception { MatrixProject matrixProject = j.jenkins.createProject(MatrixProject.class, "p"); matrixProject.setAxes(new AxisList(new Axis("foo", "a", "b"))); @@ -238,7 +238,7 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListen FreeStyleBuild build = builds.iterator().next(); assertEquals(Result.SUCCESS, build.getResult()); List downstream = j.jenkins.getDependencyGraph().getDownstream(matrixProject); - assertTrue(downstream.contains(freestyleProject)); + assertTrue(downstream.contains(freestyleProject)); List upstream = j.jenkins.getDependencyGraph().getUpstream(freestyleProject); assertTrue(upstream.contains(matrixProject)); } @@ -252,7 +252,7 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListen String oldUpstreamName = upstream.getName(); String oldDownstreamName = downstream.getName(); - + // Verify that owner entry in fingerprint record is changed // after source project is renamed upstream.renameTo(renamedProject1); @@ -264,7 +264,7 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListen assertEquals(renamedProject1, f.getOriginal().getName()); assertNotEquals(f.getOriginal().getName(), oldUpstreamName); } - + action = downstreamBuild.getAction(Fingerprinter.FingerprintAction.class); assertNotNull(action); fingerprints = action.getFingerprints().values(); @@ -273,7 +273,7 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListen assertEquals(renamedProject1, f.getOriginal().getName()); assertNotEquals(f.getOriginal().getName(), oldUpstreamName); } - + // Verify that usage entry in fingerprint record is changed after // sink project is renamed downstream.renameTo(renamedProject2); @@ -283,7 +283,7 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListen fingerprints = action.getFingerprints().values(); for (Fingerprint f: fingerprints) { List jobs = f.getJobs(); - + assertTrue(jobs.contains(renamedProject2)); assertFalse(jobs.contains(oldDownstreamName)); } @@ -293,7 +293,7 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListen fingerprints = action.getFingerprints().values(); for (Fingerprint f: fingerprints) { List jobs = f.getJobs(); - + assertTrue(jobs.contains(renamedProject2)); assertFalse(jobs.contains(oldDownstreamName)); } @@ -378,15 +378,15 @@ public void fingerprintCleanup() throws Exception { assertEquals(1,f.getUsages().size()); } - + private FreeStyleProject createFreeStyleProjectWithFingerprints(String[] contents, String[] files) throws Exception { FreeStyleProject project = j.createFreeStyleProject(); addFingerprinterToProject(project, contents, files); - + return project; } - + private void addFingerprinterToProject(AbstractProject project, String[] contents, String[] files) { StringBuilder targets = new StringBuilder(); for (int i = 0; i < contents.length; i++) { @@ -401,7 +401,7 @@ private void addFingerprinterToProject(AbstractProject project, String[] c ? new BatchFile("echo " + contents[i] + "> " + files[i]) : new Shell("echo " + contents[i] + " > " + files[i])); } - + targets.append(files[i]).append(','); } diff --git a/test/src/test/java/hudson/tasks/LogRotatorTest.java b/test/src/test/java/hudson/tasks/LogRotatorTest.java index 4c74d8acd1d4..30af65c87b60 100644 --- a/test/src/test/java/hudson/tasks/LogRotatorTest.java +++ b/test/src/test/java/hudson/tasks/LogRotatorTest.java @@ -146,7 +146,7 @@ public void artifactDelete() throws Exception { assertTrue(project.getBuildByNumber(7).getHasArtifacts()); assertTrue(project.getBuildByNumber(8).getHasArtifacts()); } - + @Test @Issue("JENKINS-27836") public void artifactsRetainedWhileBuilding() throws Exception { @@ -179,7 +179,7 @@ public void artifactsRetainedWhileBuilding() throws Exception { assertThat("run1 is last stable build", p.getLastStableBuild(), is(run1)); assertThat("run1 is last successful build", p.getLastSuccessfulBuild(), is(run1)); assertThat("we have artifacts in run1", run1.getHasArtifacts(), is(true)); - assertThat("CRITICAL ASSERTION: we have artifacts in run2", run2.getHasArtifacts(), is(true)); + assertThat("CRITICAL ASSERTION: we have artifacts in run2", run2.getHasArtifacts(), is(true)); assertThat("we have artifacts in run3", run3.getHasArtifacts(), is(true)); sync.release(run2.getNumber()); futureRun2.get(); @@ -221,17 +221,17 @@ public Descriptor getDescriptor() { return new Descriptor(TestsFail.class) {}; } } - + public static class StallBuilder extends TestBuilder { - + private int syncBuildNumber; - + private final Object syncLock = new Object(); - + private int waitBuildNumber; - + private final Object waitLock = new Object(); - + private final ArtifactArchiver archiver = new ArtifactArchiver("f"); @Override @@ -259,7 +259,7 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListene Logger.getAnonymousLogger().log(Level.INFO, "Done #{0}", build.getNumber()); return true; } - + public void release(int upToBuildNumber) { synchronized (syncLock) { if (syncBuildNumber < upToBuildNumber) { @@ -269,7 +269,7 @@ public void release(int upToBuildNumber) { } } } - + public void waitFor(int buildNumber, long timeout, TimeUnit units) throws TimeoutException, InterruptedException { long giveUp = System.nanoTime() + units.toNanos(timeout); diff --git a/test/src/test/java/hudson/tasks/MavenTest.java b/test/src/test/java/hudson/tasks/MavenTest.java index 5276b52381f8..cb6e35d98ced 100644 --- a/test/src/test/java/hudson/tasks/MavenTest.java +++ b/test/src/test/java/hudson/tasks/MavenTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Yahoo! Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -95,7 +95,7 @@ public class MavenTest { assertEquals("b.pom", m.pom); assertEquals("c=d", m.properties); assertEquals("-e", m.jvmOptions); - assertTrue(m.usesPrivateRepository()); + assertTrue(m.usesPrivateRepository()); } @Test public void withNodeProperty() throws Exception { @@ -202,7 +202,7 @@ private void verify() throws Exception { FreeStyleBuild build = j.waitForCompletion(project.scheduleBuild2(0).waitForStart()); j.assertLogNotContains("-Dpassword=12345", build); } - + @Test public void parametersReferencedFromPropertiesShouldRetainBackslashes() throws Exception { final String properties = "global.path=$GLOBAL_PATH\nmy.path=$PATH\\\\Dir"; @@ -227,22 +227,22 @@ public void parametersReferencedFromPropertiesShouldRetainBackslashes() throws E { FreeStyleProject p = j.createFreeStyleProject(); p.getBuildersList().add(new Maven("a", null, "a.pom", "c=d", "-e", true)); - + Maven m = p.getBuildersList().get(Maven.class); assertNotNull(m); assertEquals(DefaultSettingsProvider.class, m.getSettings().getClass()); assertEquals(DefaultGlobalSettingsProvider.class, m.getGlobalSettings().getClass()); } - + { GlobalMavenConfig globalMavenConfig = GlobalMavenConfig.get(); assertNotNull("No global Maven Config available", globalMavenConfig); globalMavenConfig.setSettingsProvider(new FilePathSettingsProvider("/tmp/settings.xml")); globalMavenConfig.setGlobalSettingsProvider(new FilePathGlobalSettingsProvider("/tmp/global-settings.xml")); - + FreeStyleProject p = j.createFreeStyleProject(); p.getBuildersList().add(new Maven("b", null, "b.pom", "c=d", "-e", true)); - + Maven m = p.getBuildersList().get(Maven.class); assertEquals(FilePathSettingsProvider.class, m.getSettings().getClass()); assertEquals("/tmp/settings.xml", ((FilePathSettingsProvider)m.getSettings()).getPath()); diff --git a/test/src/test/java/hudson/tasks/UserAvatarResolverTest.java b/test/src/test/java/hudson/tasks/UserAvatarResolverTest.java index bb123e3c5e40..06fc2f0811c2 100644 --- a/test/src/test/java/hudson/tasks/UserAvatarResolverTest.java +++ b/test/src/test/java/hudson/tasks/UserAvatarResolverTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2011, Erik Ramfelt - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/test/src/test/java/hudson/tools/ZipExtractionInstallerTest.java b/test/src/test/java/hudson/tools/ZipExtractionInstallerTest.java index 8bb0643b8bf3..e0adc3826879 100644 --- a/test/src/test/java/hudson/tools/ZipExtractionInstallerTest.java +++ b/test/src/test/java/hudson/tools/ZipExtractionInstallerTest.java @@ -59,93 +59,93 @@ import org.jvnet.hudson.test.MockAuthorizationStrategy; public class ZipExtractionInstallerTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Rule public TemporaryFolder tmp = new TemporaryFolder(); - + @Test @Issue("SECURITY-794") public void onlyAdminCanReachTheDoCheck() throws Exception { final String ADMIN = "admin"; final String USER = "user"; - + j.jenkins.setCrumbIssuer(null); j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() .grant(Jenkins.ADMINISTER).everywhere().to(ADMIN) .grant(Jenkins.READ).everywhere().to(USER) ); - + User.getById(ADMIN, true); User.getById(USER, true); - + WebRequest request = new WebRequest(new URL(j.getURL() + "descriptorByName/hudson.tools.ZipExtractionInstaller/checkUrl"), HttpMethod.POST); request.setRequestBody(URLEncoder.encode("value=https://www.google.com", StandardCharsets.UTF_8.name())); - + JenkinsRule.WebClient adminWc = j.createWebClient(); adminWc.login(ADMIN); assertEquals(HttpURLConnection.HTTP_OK, adminWc.getPage(request).getWebResponse().getStatusCode()); - + JenkinsRule.WebClient userWc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); userWc.login(USER); assertEquals(HttpURLConnection.HTTP_FORBIDDEN, userWc.getPage(request).getWebResponse().getStatusCode()); } - + @Test @Issue("SECURITY-794") public void roundtrip() throws Exception { final String VALID_URL = "https://www.google.com"; final String INVALID_URL = "only-crappy-letters"; - + ZipExtractionInstaller installer = new ZipExtractionInstaller("", VALID_URL, ""); - + j.jenkins.getJDKs().add(new JDK("test", tmp.getRoot().getAbsolutePath(), Collections.singletonList( new InstallSourceProperty(Collections.singletonList(installer))))); - + JenkinsRule.WebClient wc = j.createWebClient(); - + SpyingJavaScriptEngine jsEngine = new SpyingJavaScriptEngine(wc, "ZipExtractionInstaller/checkUrl", HttpMethod.POST); wc.setJavaScriptEngine(jsEngine); - + HtmlPage page = wc.goTo("configureTools"); - + XMLHttpRequest lastRequest = jsEngine.getLastRequest(); String body = URLDecoder.decode(getPrivateWebRequestField(lastRequest).getRequestBody(), "UTF-8"); assertThat(body, containsString(VALID_URL)); assertEquals(FormValidation.ok().renderHtml(), lastRequest.getResponseText()); - + HtmlTextInput urlInput = page.getDocumentElement().getOneHtmlElementByAttribute("input", "value", VALID_URL); urlInput.setAttribute("value", INVALID_URL); j.submit(page.getFormByName("config")); - + JDK jdk = j.jenkins.getJDK("test"); InstallSourceProperty isp = jdk.getProperties().get(InstallSourceProperty.class); assertEquals(1, isp.installers.size()); assertEquals(INVALID_URL, isp.installers.get(ZipExtractionInstaller.class).getUrl()); - + wc.goTo("configureTools"); - + lastRequest = jsEngine.getLastRequest(); body = URLDecoder.decode(getPrivateWebRequestField(lastRequest).getRequestBody(), "UTF-8"); assertThat(body, containsString(INVALID_URL)); assertThat(lastRequest.getResponseText(), containsString(Messages.ZipExtractionInstaller_malformed_url())); } - + private static class SpyingJavaScriptEngine extends JavaScriptEngine { private List storedRequests = new ArrayList<>(); private String urlToMatch; private HttpMethod method; - + SpyingJavaScriptEngine(JenkinsRule.WebClient wc, @Nullable String urlToMatch, @Nullable HttpMethod method) { super(wc); this.urlToMatch = urlToMatch; this.method = method; } - + @Override public Object callFunction(HtmlPage page, Function function, Scriptable scope, Scriptable thisObject, Object[] args) { if (thisObject instanceof XMLHttpRequest) { @@ -164,7 +164,7 @@ public Object callFunction(HtmlPage page, Function function, Scriptable scope, S } return super.callFunction(page, function, scope, thisObject, args); } - + @NonNull public XMLHttpRequest getLastRequest() { if (storedRequests.isEmpty()) { @@ -173,7 +173,7 @@ public XMLHttpRequest getLastRequest() { return storedRequests.get(storedRequests.size() - 1); } } - + private static WebRequest getPrivateWebRequestField(XMLHttpRequest xmlHttpRequest) throws NoSuchFieldException, IllegalAccessException { Field webRequest_Field = XMLHttpRequest.class.getDeclaredField("webRequest_"); webRequest_Field.setAccessible(true); diff --git a/test/src/test/java/hudson/triggers/SCMTriggerTest.java b/test/src/test/java/hudson/triggers/SCMTriggerTest.java index e5f8a6f3f107..40051a235ec1 100644 --- a/test/src/test/java/hudson/triggers/SCMTriggerTest.java +++ b/test/src/test/java/hudson/triggers/SCMTriggerTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/test/src/test/java/hudson/util/BootFailureTest.java b/test/src/test/java/hudson/util/BootFailureTest.java index 22b9b39a1955..c1ebabf8d7fc 100644 --- a/test/src/test/java/hudson/util/BootFailureTest.java +++ b/test/src/test/java/hudson/util/BootFailureTest.java @@ -75,7 +75,7 @@ public WebAppMain.FileAndDescription getHomeDir(ServletContextEvent event) { if (noListenerConfiguration != null) { context.removeBean(noListenerConfiguration); context.addBean(new AbstractLifeCycle() { - @Override + @Override protected void doStart() { // default behavior of noListenerConfiguration context.setEventListeners(null); diff --git a/test/src/test/java/hudson/util/RobustReflectionConverterTest.java b/test/src/test/java/hudson/util/RobustReflectionConverterTest.java index b3e03bd0ad47..ad04d0111bb9 100644 --- a/test/src/test/java/hudson/util/RobustReflectionConverterTest.java +++ b/test/src/test/java/hudson/util/RobustReflectionConverterTest.java @@ -77,7 +77,7 @@ public class RobustReflectionConverterTest { String text = data.values().iterator().next().extra; assertTrue(text, text.contains("hudson.triggers.TimerTrigger.readResolve")); } - + // Testing describable object to demonstrate what is expected with RobustReflectionConverter#addCriticalField // This should be configured with a specific keyword, // and should reject configurations with other keywords. @@ -87,20 +87,20 @@ public class RobustReflectionConverterTest { public static class AcceptOnlySpecificKeyword extends AbstractDescribableImpl { public static final String ACCEPT_KEYWORD = "accept"; private final String keyword; - + @DataBoundConstructor public AcceptOnlySpecificKeyword(String keyword) { this.keyword = keyword; } - + public String getKeyword() { return keyword; } - + public boolean isAcceptable() { return ACCEPT_KEYWORD.equals(keyword); } - + private Object readResolve() throws Exception { if (!ACL.SYSTEM2.equals(Jenkins.getAuthentication2())) { // called via REST / CLI with authentication @@ -111,14 +111,14 @@ private Object readResolve() throws Exception { } return this; } - + @TestExtension public static class DescriptorImpl extends Descriptor { @Override public String getDisplayName() { return "AcceptOnlySpecificKeyword"; } - + @Override public AcceptOnlySpecificKeyword newInstance(StaplerRequest req, JSONObject formData) throws FormException { @@ -130,31 +130,31 @@ public AcceptOnlySpecificKeyword newInstance(StaplerRequest req, JSONObject form } } } - + public static class KeywordProperty extends JobProperty> { private final AcceptOnlySpecificKeyword nonCriticalField; private final AcceptOnlySpecificKeyword criticalField; - + public KeywordProperty(AcceptOnlySpecificKeyword nonCriticalField, AcceptOnlySpecificKeyword criticalField) { this.nonCriticalField = nonCriticalField; this.criticalField = criticalField; } - + public AcceptOnlySpecificKeyword getNonCriticalField() { return nonCriticalField; } - + public AcceptOnlySpecificKeyword getCriticalField() { return criticalField; } - + @TestExtension public static class DescriptorImpl extends JobPropertyDescriptor { @Override public String getDisplayName() { return "KeywordProperty"; } - + @Override public JobProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { @@ -169,7 +169,7 @@ public JobProperty newInstance(StaplerRequest req, JSONObject formData) } } } - + private static final String CONFIGURATION_TEMPLATE = "" + "" @@ -184,7 +184,7 @@ public JobProperty newInstance(StaplerRequest req, JSONObject formData) + "" + "" + ""; - + @Test public void testRestInterfaceFailure() throws Exception { Items.XSTREAM2.addCriticalField(KeywordProperty.class, "criticalField"); @@ -197,7 +197,7 @@ public void testRestInterfaceFailure() throws Exception { new AcceptOnlySpecificKeyword(AcceptOnlySpecificKeyword.ACCEPT_KEYWORD) )); p.save(); - + // Configure a bad keyword via REST. r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); WebClient wc = r.createWebClient(); @@ -206,19 +206,19 @@ public void testRestInterfaceFailure() throws Exception { req.setEncodingType(null); req.setRequestBody(String.format(CONFIGURATION_TEMPLATE, "badvalue", AcceptOnlySpecificKeyword.ACCEPT_KEYWORD)); wc.getPage(req); - + // AcceptOnlySpecificKeyword with bad value is not instantiated for rejected with readResolve, assertNull(p.getProperty(KeywordProperty.class).getNonCriticalField()); assertEquals(AcceptOnlySpecificKeyword.ACCEPT_KEYWORD, p.getProperty(KeywordProperty.class).getCriticalField().getKeyword()); - + // but save to the disk. r.jenkins.reload(); - + p = r.jenkins.getItemByFullName(p.getFullName(), FreeStyleProject.class); assertEquals("badvalue", p.getProperty(KeywordProperty.class).getNonCriticalField().getKeyword()); assertEquals(AcceptOnlySpecificKeyword.ACCEPT_KEYWORD, p.getProperty(KeywordProperty.class).getCriticalField().getKeyword()); } - + // with addCriticalField. This is not accepted. { FreeStyleProject p = r.createFreeStyleProject(); @@ -227,7 +227,7 @@ public void testRestInterfaceFailure() throws Exception { new AcceptOnlySpecificKeyword(AcceptOnlySpecificKeyword.ACCEPT_KEYWORD) )); p.save(); - + // Configure a bad keyword via REST. r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); WebClient wc = r.createWebClient() @@ -236,27 +236,27 @@ public void testRestInterfaceFailure() throws Exception { WebRequest req = new WebRequest(new URL(wc.getContextPath() + String.format("%s/config.xml", p.getUrl())), HttpMethod.POST); req.setEncodingType(null); req.setRequestBody(String.format(CONFIGURATION_TEMPLATE, AcceptOnlySpecificKeyword.ACCEPT_KEYWORD, "badvalue")); - + Page page = wc.getPage(req); - assertEquals("Submitting unacceptable configuration via REST should fail.", + assertEquals("Submitting unacceptable configuration via REST should fail.", HttpURLConnection.HTTP_INTERNAL_ERROR, page.getWebResponse().getStatusCode()); - + // Configuration should not be updated for a failure of the critical field, assertNotEquals("badvalue", p.getProperty(KeywordProperty.class).getCriticalField().getKeyword()); - + r.jenkins.reload(); - + // rejected configuration is not saved p = r.jenkins.getItemByFullName(p.getFullName(), FreeStyleProject.class); assertNotEquals("badvalue", p.getProperty(KeywordProperty.class).getCriticalField().getKeyword()); } } - + @Test public void testCliFailure() throws Exception { Items.XSTREAM2.addCriticalField(KeywordProperty.class, "criticalField"); - + // without addCriticalField. This is accepted. { FreeStyleProject p = r.createFreeStyleProject(); @@ -265,10 +265,10 @@ public void testCliFailure() throws Exception { new AcceptOnlySpecificKeyword(AcceptOnlySpecificKeyword.ACCEPT_KEYWORD) )); p.save(); - + // Configure a bad keyword via CLI. r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); - + CLICommandInvoker.Result ret = new CLICommandInvoker(r, "update-job") .asUser("test") .withStdin(new ByteArrayInputStream(String.format(CONFIGURATION_TEMPLATE, "badvalue", AcceptOnlySpecificKeyword.ACCEPT_KEYWORD).getBytes())) @@ -276,20 +276,20 @@ public void testCliFailure() throws Exception { p.getFullName() ) .invoke(); - + assertEquals(0, ret.returnCode()); - + // AcceptOnlySpecificKeyword with bad value is not instantiated for rejected with readResolve, assertNull(p.getProperty(KeywordProperty.class).getNonCriticalField()); assertEquals(AcceptOnlySpecificKeyword.ACCEPT_KEYWORD, p.getProperty(KeywordProperty.class).getCriticalField().getKeyword()); - + // but save to the disk. r.jenkins.reload(); - + p = r.jenkins.getItemByFullName(p.getFullName(), FreeStyleProject.class); assertEquals("badvalue", p.getProperty(KeywordProperty.class).getNonCriticalField().getKeyword()); } - + // with addCriticalField. This is not accepted. { FreeStyleProject p = r.createFreeStyleProject(); @@ -298,7 +298,7 @@ public void testCliFailure() throws Exception { new AcceptOnlySpecificKeyword(AcceptOnlySpecificKeyword.ACCEPT_KEYWORD) )); p.save(); - + // Configure a bad keyword via CLI. r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); CLICommandInvoker.Result ret = new CLICommandInvoker(r, "update-job") @@ -309,12 +309,12 @@ public void testCliFailure() throws Exception { ) .invoke(); assertNotEquals(0, ret.returnCode()); - + // Configuration should not be updated for a failure of the critical field, assertNotEquals("badvalue", p.getProperty(KeywordProperty.class).getCriticalField().getKeyword()); - + r.jenkins.reload(); - + // rejected configuration is not saved p = r.jenkins.getItemByFullName(p.getFullName(), FreeStyleProject.class); assertNotEquals("badvalue", p.getProperty(KeywordProperty.class).getCriticalField().getKeyword()); diff --git a/test/src/test/java/hudson/views/GlobalDefaultViewConfigurationTest.java b/test/src/test/java/hudson/views/GlobalDefaultViewConfigurationTest.java index 8a55ce612281..c4d5c8042ee8 100644 --- a/test/src/test/java/hudson/views/GlobalDefaultViewConfigurationTest.java +++ b/test/src/test/java/hudson/views/GlobalDefaultViewConfigurationTest.java @@ -41,27 +41,27 @@ * @author Oleg Nenashev */ public class GlobalDefaultViewConfigurationTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Test @Issue("JENKINS-42717") public void shouldNotFailIfTheDefaultViewIsMissing() { String viewName = "NonExistentView"; GlobalDefaultViewConfiguration c = new GlobalDefaultViewConfiguration(); - + StaplerRequest create = new MockStaplerRequestBuilder(j, "/configure").build(); JSONObject params = new JSONObject(); params.accumulate("primaryView", viewName); try { c.configure(create, params); } catch(Descriptor.FormException ex) { - assertThat("Wrong exception message for the form failure", + assertThat("Wrong exception message for the form failure", ex.getMessage(), containsString(Messages.GlobalDefaultViewConfiguration_ViewDoesNotExist(viewName))); return; } Assert.fail("Expected FormException"); } - + } diff --git a/test/src/test/java/jenkins/AgentProtocolTest.java b/test/src/test/java/jenkins/AgentProtocolTest.java index 3f0bac4e2265..9f221e6ad780 100644 --- a/test/src/test/java/jenkins/AgentProtocolTest.java +++ b/test/src/test/java/jenkins/AgentProtocolTest.java @@ -38,11 +38,11 @@ /** * Tests for {@link AgentProtocol}. - * + * * @author Oleg Nenashev */ public class AgentProtocolTest { - + @Rule public JenkinsRule j = new JenkinsRule(); @@ -54,19 +54,19 @@ public void testShouldNotOverrideUserConfiguration() throws Exception { assertDisabled("JNLP2-connect", "JNLP4-connect"); assertProtocols(true, "System protocols should be always enabled", "Ping"); } - + private void assertEnabled(String ... protocolNames) { - assertProtocols(true, null, protocolNames); + assertProtocols(true, null, protocolNames); } - + private void assertDisabled(String ... protocolNames) { - assertProtocols(false, null, protocolNames); + assertProtocols(false, null, protocolNames); } - + private void assertProtocols(boolean shouldBeEnabled, @CheckForNull String why, String ... protocolNames) { assertProtocols(j.jenkins, shouldBeEnabled, why, protocolNames); } - + public static void assertProtocols(Jenkins jenkins, boolean shouldBeEnabled, @CheckForNull String why, String ... protocolNames) { Set agentProtocols = jenkins.getAgentProtocols(); List failedChecks = new ArrayList<>(); @@ -78,7 +78,7 @@ public static void assertProtocols(Jenkins jenkins, boolean shouldBeEnabled, @Ch failedChecks.add(protocol); } } - + if (!failedChecks.isEmpty()) { String message = String.format("Protocol(s) are not %s: %s. %sEnabled protocols: %s", shouldBeEnabled ? "enabled" : "disabled", @@ -88,5 +88,5 @@ public static void assertProtocols(Jenkins jenkins, boolean shouldBeEnabled, @Ch fail(message); } } - + } diff --git a/test/src/test/java/jenkins/diagnostics/ControllerExecutorsAgentsTest.java b/test/src/test/java/jenkins/diagnostics/ControllerExecutorsAgentsTest.java index 27cdedca00d1..f55bc93706c2 100644 --- a/test/src/test/java/jenkins/diagnostics/ControllerExecutorsAgentsTest.java +++ b/test/src/test/java/jenkins/diagnostics/ControllerExecutorsAgentsTest.java @@ -34,10 +34,10 @@ import org.jvnet.hudson.test.JenkinsRule; public class ControllerExecutorsAgentsTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Test public void testInitial() { ControllerExecutorsAgents monitor = j.jenkins.getExtensionList(AdministrativeMonitor.class).get(ControllerExecutorsAgents.class); diff --git a/test/src/test/java/jenkins/diagnostics/ControllerExecutorsNoAgentsTest.java b/test/src/test/java/jenkins/diagnostics/ControllerExecutorsNoAgentsTest.java index 4ef629182090..4a1d582067e1 100644 --- a/test/src/test/java/jenkins/diagnostics/ControllerExecutorsNoAgentsTest.java +++ b/test/src/test/java/jenkins/diagnostics/ControllerExecutorsNoAgentsTest.java @@ -35,10 +35,10 @@ import org.jvnet.hudson.test.JenkinsRule; public class ControllerExecutorsNoAgentsTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Test public void testInitial() { ControllerExecutorsNoAgents monitor = j.jenkins.getExtensionList(AdministrativeMonitor.class).get(ControllerExecutorsNoAgents.class); diff --git a/test/src/test/java/jenkins/diagnostics/RootUrlNotSetMonitorTest.java b/test/src/test/java/jenkins/diagnostics/RootUrlNotSetMonitorTest.java index 47defcd3b229..ea1604a3f7e7 100644 --- a/test/src/test/java/jenkins/diagnostics/RootUrlNotSetMonitorTest.java +++ b/test/src/test/java/jenkins/diagnostics/RootUrlNotSetMonitorTest.java @@ -35,30 +35,30 @@ import org.jvnet.hudson.test.JenkinsRule; public class RootUrlNotSetMonitorTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Test @Issue("JENKINS-31661") public void testWithRootUrl_configured() { // test relies on the default JTH behavior JenkinsLocationConfiguration config = JenkinsLocationConfiguration.get(); assertTrue(StringUtils.isNotBlank(config.getUrl())); - + RootUrlNotSetMonitor monitor = j.jenkins.getExtensionList(AdministrativeMonitor.class).get(RootUrlNotSetMonitor.class); assertFalse("Monitor must not be activated", monitor.isActivated()); - + config.setUrl(null); - + assertTrue("Monitor must be activated", monitor.isActivated()); - + config.setUrl("ftp://localhost:8080/jenkins"); - + assertTrue("Monitor must be activated", monitor.isActivated()); - + config.setUrl("http://localhost:8080/jenkins"); - + assertFalse("Monitor must be activated", monitor.isActivated()); } } diff --git a/test/src/test/java/jenkins/install/InstallStateTest.java b/test/src/test/java/jenkins/install/InstallStateTest.java index 17e76721cedd..64a119729095 100644 --- a/test/src/test/java/jenkins/install/InstallStateTest.java +++ b/test/src/test/java/jenkins/install/InstallStateTest.java @@ -45,23 +45,23 @@ */ @Category(SmokeTest.class) public class InstallStateTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Test public void shouldPerformCorrectConversionForAllNames() { ExtensionList states = InstallState.all(); for (InstallState state : states) { InstallState afterRoundtrip = forName(state.name()); // It also prevents occasional name duplications - assertThat("State after the roundtrip must be equal to the original state", + assertThat("State after the roundtrip must be equal to the original state", afterRoundtrip, equalTo(state)); - assertSame("State " + state + " should return the extension point instance after deserialization", + assertSame("State " + state + " should return the extension point instance after deserialization", afterRoundtrip, state); } } - + @Test @Issue("JENKINS-35206") public void shouldNotFailOnNullXMLField() { @@ -71,21 +71,21 @@ public void shouldNotFailOnNullXMLField() { final InstallState state = forXml(xml); assertThat(state, equalTo(InstallState.UNKNOWN)); } - + @Test @Issue("JENKINS-35206") public void shouldNotFailOnEmptyName() { final InstallState state = forName(""); assertThat(state, equalTo(InstallState.UNKNOWN)); } - + @Test @Issue("JENKINS-35206") public void shouldReturnUnknownStateForUnknownName() { final InstallState state = forName("NonExistentStateName"); assertThat(state, equalTo(InstallState.UNKNOWN)); } - + private static InstallState forName(String name) { String xml = "\n" + " true\n" + @@ -93,7 +93,7 @@ private static InstallState forName(String name) { ""; return forXml(xml); } - + private static InstallState forXml(String xml) { Object read = Jenkins.XSTREAM2.fromXML(xml); assertThat(read, instanceOf(InstallState.class)); diff --git a/test/src/test/java/jenkins/install/SetupWizardTest.java b/test/src/test/java/jenkins/install/SetupWizardTest.java index cf9897ec118e..11661cf433db 100644 --- a/test/src/test/java/jenkins/install/SetupWizardTest.java +++ b/test/src/test/java/jenkins/install/SetupWizardTest.java @@ -75,22 +75,22 @@ public class SetupWizardTest { @Rule public JenkinsRule j = new JenkinsRule(); - + @Rule public TemporaryFolder tmpdir = new TemporaryFolder(); - - @Before + + @Before public void initSetupWizard() throws IOException, InterruptedException { final SetupWizard wizard = j.jenkins.getSetupWizard(); wizard.init(true); - + // Retrieve admin credentials final FilePath adminPassFile = wizard.getInitialAdminPasswordFile(); ByteArrayOutputStream ostream = new ByteArrayOutputStream(); adminPassFile.copyTo(ostream); final String password = ostream.toString(); } - + @Test public void shouldReturnPluginListsByDefault() throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); @@ -99,7 +99,7 @@ public void shouldReturnPluginListsByDefault() throws Exception { j.jenkins.setAuthorizationStrategy(AuthorizationStrategy.UNSECURED); // wc.setCredentialsProvider(adminCredentialsProvider); // wc.login("admin"); - + String response = jsonRequest(wc, "setupWizard/platformPluginList"); assertThat("Missing plugin is suggestions ", response, containsString("active-directory")); assertThat("Missing category is suggestions ", response, containsString("Pipelines and Continuous Delivery")); diff --git a/test/src/test/java/jenkins/model/JenkinsBuildsAndWorkspacesDirectoriesTest.java b/test/src/test/java/jenkins/model/JenkinsBuildsAndWorkspacesDirectoriesTest.java index f5e6c471eb6d..c3f476e6a40b 100644 --- a/test/src/test/java/jenkins/model/JenkinsBuildsAndWorkspacesDirectoriesTest.java +++ b/test/src/test/java/jenkins/model/JenkinsBuildsAndWorkspacesDirectoriesTest.java @@ -275,10 +275,10 @@ private boolean logWasFound(String searched) { .anyMatch(record -> record.getMessage().contains(searched)); } - private boolean logWasFoundAtLevel(String searched, Level level) { - return loggerRule.getRecords().stream() + private boolean logWasFoundAtLevel(String searched, Level level) { + return loggerRule.getRecords().stream() .filter(record -> record.getMessage().contains(searched)).anyMatch(record -> record.getLevel().equals(level)); - } + } @Test @Issue("JENKINS-17138") diff --git a/test/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java b/test/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java index 86f2c0ea4b64..db9ea9a58370 100644 --- a/test/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java +++ b/test/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java @@ -51,7 +51,7 @@ public URL getURL() throws IOException { return super.getURL(); } }; - + /** * Makes sure the use of "localhost" in the Hudson URL reports a warning. */ diff --git a/test/src/test/java/jenkins/model/JenkinsTest.java b/test/src/test/java/jenkins/model/JenkinsTest.java index e52a7b679cbe..b476a317136b 100644 --- a/test/src/test/java/jenkins/model/JenkinsTest.java +++ b/test/src/test/java/jenkins/model/JenkinsTest.java @@ -125,10 +125,10 @@ public void testIsDisplayNameUniqueTrue() throws Exception { final String jobName = "jobName"; FreeStyleProject curProject = j.createFreeStyleProject(curJobName); curProject.setDisplayName("currentProjectDisplayName"); - + FreeStyleProject p = j.createFreeStyleProject(jobName); p.setDisplayName("displayName"); - + Jenkins jenkins = Jenkins.get(); assertTrue(jenkins.isDisplayNameUnique("displayName1", curJobName)); assertTrue(jenkins.isDisplayNameUnique(jobName, curJobName)); @@ -139,37 +139,37 @@ public void testIsDisplayNameUniqueFalse() throws Exception { final String curJobName = "curJobName"; final String jobName = "jobName"; final String displayName = "displayName"; - + FreeStyleProject curProject = j.createFreeStyleProject(curJobName); curProject.setDisplayName("currentProjectDisplayName"); - + FreeStyleProject p = j.createFreeStyleProject(jobName); p.setDisplayName(displayName); - + Jenkins jenkins = Jenkins.get(); assertFalse(jenkins.isDisplayNameUnique(displayName, curJobName)); } - + @Test public void testIsDisplayNameUniqueSameAsCurrentJob() throws Exception { final String curJobName = "curJobName"; final String displayName = "currentProjectDisplayName"; - + FreeStyleProject curProject = j.createFreeStyleProject(curJobName); curProject.setDisplayName(displayName); - + Jenkins jenkins = Jenkins.get(); // should be true as we don't test against the current job assertTrue(jenkins.isDisplayNameUnique(displayName, curJobName)); } - + @Test public void testIsNameUniqueTrue() throws Exception { final String curJobName = "curJobName"; final String jobName = "jobName"; j.createFreeStyleProject(curJobName); j.createFreeStyleProject(jobName); - + Jenkins jenkins = Jenkins.get(); assertTrue(jenkins.isNameUnique("jobName1", curJobName)); } @@ -180,7 +180,7 @@ public void testIsNameUniqueFalse() throws Exception { final String jobName = "jobName"; j.createFreeStyleProject(curJobName); j.createFreeStyleProject(jobName); - + Jenkins jenkins = Jenkins.get(); assertFalse(jenkins.isNameUnique(jobName, curJobName)); } @@ -191,22 +191,22 @@ public void testIsNameUniqueSameAsCurrentJob() throws Exception { final String jobName = "jobName"; j.createFreeStyleProject(curJobName); j.createFreeStyleProject(jobName); - + Jenkins jenkins = Jenkins.get(); // true because we don't test against the current job assertTrue(jenkins.isNameUnique(curJobName, curJobName)); } - + @Test public void testDoCheckDisplayNameUnique() throws Exception { final String curJobName = "curJobName"; final String jobName = "jobName"; FreeStyleProject curProject = j.createFreeStyleProject(curJobName); curProject.setDisplayName("currentProjectDisplayName"); - + FreeStyleProject p = j.createFreeStyleProject(jobName); p.setDisplayName("displayName"); - + Jenkins jenkins = Jenkins.get(); FormValidation v = jenkins.doCheckDisplayName("1displayName", curJobName); assertEquals(FormValidation.ok(), v); @@ -219,10 +219,10 @@ public void testDoCheckDisplayNameSameAsDisplayName() throws Exception { final String displayName = "displayName"; FreeStyleProject curProject = j.createFreeStyleProject(curJobName); curProject.setDisplayName("currentProjectDisplayName"); - + FreeStyleProject p = j.createFreeStyleProject(jobName); p.setDisplayName(displayName); - + Jenkins jenkins = Jenkins.get(); FormValidation v = jenkins.doCheckDisplayName(displayName, curJobName); assertEquals(FormValidation.Kind.WARNING, v.kind); @@ -235,10 +235,10 @@ public void testDoCheckDisplayNameSameAsJobName() throws Exception { final String displayName = "displayName"; FreeStyleProject curProject = j.createFreeStyleProject(curJobName); curProject.setDisplayName("currentProjectDisplayName"); - + FreeStyleProject p = j.createFreeStyleProject(jobName); p.setDisplayName(displayName); - + Jenkins jenkins = Jenkins.get(); FormValidation v = jenkins.doCheckDisplayName(jobName, curJobName); assertEquals(FormValidation.Kind.WARNING, v.kind); @@ -250,7 +250,7 @@ public void testDoCheckViewName_GoodName() throws Exception { "", "Jenkins", }; - + Jenkins jenkins = Jenkins.get(); for (String viewName : viewNames) { FormValidation v = jenkins.doCheckViewName(viewName); @@ -272,15 +272,15 @@ public void testDoCheckViewName_NotGoodName() throws Exception { "^Jenkins", "..", }; - + Jenkins jenkins = Jenkins.get(); - + for (String viewName : viewNames) { FormValidation v = jenkins.doCheckViewName(viewName); assertEquals(FormValidation.Kind.ERROR, v.kind); } } - + /** * Makes sure access to "/foobar" for UnprotectedRootAction gets through. @@ -303,7 +303,7 @@ public void testUnprotectedRootAction() throws Exception { @Test public void testDoScript() throws Exception { ApiTokenTestHelper.enableLegacyBehavior(); - + j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy(). grant(Jenkins.ADMINISTER).everywhere().to("alice"). @@ -343,7 +343,7 @@ public void testDoScriptTextDoesNotOutputExtraWhitespace() throws Exception { @Test public void testDoEval() throws Exception { ApiTokenTestHelper.enableLegacyBehavior(); - + j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy(). grant(Jenkins.ADMINISTER).everywhere().to("alice"). @@ -359,8 +359,8 @@ public void testDoEval() throws Exception { wc.withBasicApiToken(User.getById("bob", true)); Page page = eval(wc); - assertEquals("bob has only READ", - HttpURLConnection.HTTP_FORBIDDEN, + assertEquals("bob has only READ", + HttpURLConnection.HTTP_FORBIDDEN, page.getWebResponse().getStatusCode()); wc.withBasicApiToken(User.getById("charlie", true)); @@ -534,23 +534,23 @@ public void onOnline(Computer c, TaskListener listener) throws IOException, Inte @Issue("JENKINS-39465") public void agentProtocols_singleEnable_roundtrip() throws Exception { final Set defaultProtocols = Collections.unmodifiableSet(j.jenkins.getAgentProtocols()); - + final Set newProtocols = new HashSet<>(defaultProtocols); newProtocols.add(MockOptInProtocol1.NAME); j.jenkins.setAgentProtocols(newProtocols); j.jenkins.save(); final Set agentProtocolsBeforeReload = j.jenkins.getAgentProtocols(); assertProtocolEnabled(MockOptInProtocol1.NAME, "before the roundtrip"); - + j.jenkins.reload(); - + final Set reloadedProtocols = j.jenkins.getAgentProtocols(); assertNotSame("The protocol list must have been really reloaded", agentProtocolsBeforeReload, reloadedProtocols); - assertThat("We should have additional enabled protocol", + assertThat("We should have additional enabled protocol", reloadedProtocols.size(), equalTo(defaultProtocols.size() + 1)); assertProtocolEnabled(MockOptInProtocol1.NAME, "after the roundtrip"); } - + @Test @Issue("JENKINS-39465") public void agentProtocols_multipleDisable_roundtrip() throws Exception { @@ -564,14 +564,14 @@ public void agentProtocols_multipleDisable_roundtrip() throws Exception { assertProtocolDisabled(MockOptOutProtocol1.NAME, "before the roundtrip"); final Set agentProtocolsBeforeReload = j.jenkins.getAgentProtocols(); j.jenkins.reload(); - + assertNotSame("The protocol list must have been really refreshed", agentProtocolsBeforeReload, j.jenkins.getAgentProtocols()); - assertThat("We should have disabled one protocol", + assertThat("We should have disabled one protocol", j.jenkins.getAgentProtocols().size(), equalTo(defaultProtocols.size() - 1)); assertProtocolDisabled(MockOptOutProtocol1.NAME, "after the roundtrip"); } - + @Test @Issue("JENKINS-39465") public void agentProtocols_multipleEnable_roundtrip() throws Exception { @@ -587,7 +587,7 @@ public void agentProtocols_multipleEnable_roundtrip() throws Exception { assertProtocolEnabled(MockOptInProtocol2.NAME, "before the roundtrip"); j.jenkins.reload(); - + final Set reloadedProtocols = j.jenkins.getAgentProtocols(); assertNotSame("The protocol list must have been really reloaded", agentProtocolsBeforeReload, reloadedProtocols); assertThat("There should be two additional enabled protocols", @@ -595,14 +595,14 @@ public void agentProtocols_multipleEnable_roundtrip() throws Exception { assertProtocolEnabled(MockOptInProtocol1.NAME, "after the roundtrip"); assertProtocolEnabled(MockOptInProtocol2.NAME, "after the roundtrip"); } - + @Test @Issue("JENKINS-39465") public void agentProtocols_singleDisable_roundtrip() throws Exception { final Set defaultProtocols = Collections.unmodifiableSet(j.jenkins.getAgentProtocols()); final String protocolToDisable1 = MockOptOutProtocol1.NAME; final String protocolToDisable2 = MockOptOutProtocol2.NAME; - + final Set newProtocols = new HashSet<>(defaultProtocols); newProtocols.remove(protocolToDisable1); newProtocols.remove(protocolToDisable2); @@ -612,9 +612,9 @@ public void agentProtocols_singleDisable_roundtrip() throws Exception { assertProtocolDisabled(protocolToDisable2, "before the roundtrip"); final Set agentProtocolsBeforeReload = j.jenkins.getAgentProtocols(); j.jenkins.reload(); - + assertNotSame("The protocol list must have been really reloaded", agentProtocolsBeforeReload, j.jenkins.getAgentProtocols()); - assertThat("We should have disabled two protocols", + assertThat("We should have disabled two protocols", j.jenkins.getAgentProtocols().size(), equalTo(defaultProtocols.size() - 2)); assertProtocolDisabled(protocolToDisable1, "after the roundtrip"); assertProtocolDisabled(protocolToDisable2, "after the roundtrip"); diff --git a/test/src/test/java/jenkins/model/MasterBuildConfigurationTest.java b/test/src/test/java/jenkins/model/MasterBuildConfigurationTest.java index 6897bcbe4f16..97e894354bae 100644 --- a/test/src/test/java/jenkins/model/MasterBuildConfigurationTest.java +++ b/test/src/test/java/jenkins/model/MasterBuildConfigurationTest.java @@ -11,22 +11,22 @@ public class MasterBuildConfigurationTest { @Rule public JenkinsRule j = new JenkinsRule(); - + @Test @Issue("JENKINS-23966") public void retainMasterLabelWhenNoSlaveDefined() throws Exception { Jenkins jenkins = j.getInstance(); assertEquals("Test is for controller with no agent", 1, jenkins.getComputers().length); - + // set our own label & mode final String myTestLabel = "TestLabelx0123"; jenkins.setLabelString(myTestLabel); jenkins.setMode(Mode.EXCLUSIVE); - + // call global config page j.configRoundtrip(); - + // make sure settings were not lost assertEquals("Built in node's label is lost", myTestLabel, jenkins.getLabelString()); assertEquals("Built in node's mode is lost", Mode.EXCLUSIVE, jenkins.getMode()); diff --git a/test/src/test/java/jenkins/model/UnlabeledLoadStatisticsTest.java b/test/src/test/java/jenkins/model/UnlabeledLoadStatisticsTest.java index 47c9c47edec1..99dd173d3238 100644 --- a/test/src/test/java/jenkins/model/UnlabeledLoadStatisticsTest.java +++ b/test/src/test/java/jenkins/model/UnlabeledLoadStatisticsTest.java @@ -44,35 +44,35 @@ * @author Oleg Nenashev */ public class UnlabeledLoadStatisticsTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + private final LoadStatistics unlabeledLoad = new UnlabeledLoadStatistics(); - + @After public void clearQueue() { j.getInstance().getQueue().clear(); } - + @Test @Issue("JENKINS-28446") public void computeQueueLength() throws Exception { - final Queue queue = j.jenkins.getQueue(); + final Queue queue = j.jenkins.getQueue(); assertEquals("Queue must be empty when the test starts", 0, queue.getBuildableItems().size()); assertEquals("Statistics must return 0 when the test starts", 0, unlabeledLoad.computeQueueLength()); - + // Disable builds by default, create an agent to prevent assigning of "built-in" labels j.jenkins.setNumExecutors(0); DumbSlave slave = j.createOnlineSlave(new LabelAtom("testLabel")); slave.setMode(Node.Mode.EXCLUSIVE); - + // Init project FreeStyleProject unlabeledProject = j.createFreeStyleProject("UnlabeledProject"); unlabeledProject.setConcurrentBuild(true); FreeStyleProject labeledProject = j.createFreeStyleProject("LabeledProject"); labeledProject.setAssignedLabel(new LabelAtom("foo")); - + // Put unlabeled build into the queue unlabeledProject.scheduleBuild2(0, new ParametersAction(new StringParameterValue("FOO", "BAR1"))); queue.maintain(); @@ -80,12 +80,12 @@ public void computeQueueLength() throws Exception { unlabeledProject.scheduleBuild2(0, new ParametersAction(new StringParameterValue("FOO", "BAR2"))); queue.maintain(); assertEquals("Second Unlabeled build must be taken into account", 2, unlabeledLoad.computeQueueLength()); - + // Put labeled build into the queue labeledProject.scheduleBuild2(0); queue.maintain(); assertEquals("Labeled builds must be ignored", 2, unlabeledLoad.computeQueueLength()); - + // Allow executions of unlabeled builds on built-in node, all unlabeled builds should pass j.jenkins.setNumExecutors(1); j.buildAndAssertSuccess(unlabeledProject); @@ -93,5 +93,5 @@ public void computeQueueLength() throws Exception { assertEquals("Queue must contain the labeled project build", 1, queue.getBuildableItems().size()); assertEquals("Statistics must return 0 after all builds", 0, unlabeledLoad.computeQueueLength()); } - + } diff --git a/test/src/test/java/jenkins/security/ApiTokenPropertyTest.java b/test/src/test/java/jenkins/security/ApiTokenPropertyTest.java index f3adf7ea5697..805db3e1f3f8 100644 --- a/test/src/test/java/jenkins/security/ApiTokenPropertyTest.java +++ b/test/src/test/java/jenkins/security/ApiTokenPropertyTest.java @@ -61,7 +61,7 @@ public class ApiTokenPropertyTest { public void setupLegacyConfig(){ ApiTokenTestHelper.enableLegacyBehavior(); } - + /** * Tests the UI interaction and authentication. */ @@ -80,7 +80,7 @@ public void basics() throws Exception { // test the authentication via Token WebClient wc = createClientForUser("foo"); assertEquals(u, wc.executeOnServer(User::current)); - + // Make sure the UI shows the token to the user HtmlPage config = wc.goTo(u.getUrl() + "/configure"); HtmlForm form = config.getFormByName("config"); @@ -113,7 +113,7 @@ public void security49Upgrade() throws Exception { u.addProperty(t); assertEquals(t.getApiToken(), Util.getDigestOf(historicalInitialValue+"somethingElse")); } - + @Issue("SECURITY-200") @Test public void adminsShouldBeUnableToSeeTokensByDefault() throws Exception { @@ -121,14 +121,14 @@ public void adminsShouldBeUnableToSeeTokensByDefault() throws Exception { User u = User.getOrCreateByIdOrFullName("foo"); final ApiTokenProperty t = u.getProperty(ApiTokenProperty.class); final String token = t.getApiToken(); - + // Make sure the UI does not show the token to another user WebClient wc = createClientForUser("bar"); HtmlPage config = wc.goTo(u.getUrl() + "/configure"); HtmlForm form = config.getFormByName("config"); assertEquals(Messages.ApiTokenProperty_ChangeToken_TokenIsHidden(), form.getInputByName("_.apiToken").getValueAttribute()); } - + @Issue("SECURITY-200") @Test public void adminsShouldBeUnableToChangeTokensByDefault() throws Exception { @@ -137,13 +137,13 @@ public void adminsShouldBeUnableToChangeTokensByDefault() throws Exception { User bar = User.getOrCreateByIdOrFullName("bar"); final ApiTokenProperty t = foo.getProperty(ApiTokenProperty.class); final ApiTokenProperty.DescriptorImpl descriptor = (ApiTokenProperty.DescriptorImpl) t.getDescriptor(); - + // Make sure that Admin can reset a token of another user WebClient wc = createClientForUser("bar") .withThrowExceptionOnFailingStatusCode(false); HtmlPage requirePOST = wc.goTo(foo.getUrl() + "/" + descriptor.getDescriptorUrl()+ "/changeToken"); - assertEquals("method should not be allowed", - HttpURLConnection.HTTP_BAD_METHOD, + assertEquals("method should not be allowed", + HttpURLConnection.HTTP_BAD_METHOD, requirePOST.getWebResponse().getStatusCode()); wc.setThrowExceptionOnFailingStatusCode(true); @@ -152,7 +152,7 @@ public void adminsShouldBeUnableToChangeTokensByDefault() throws Exception { // TODO This nicer alternative requires https://github.com/jenkinsci/jenkins/pull/2268 or similar to work // HtmlPage res = requirePOST.getPage().getForms().get(0).getElementsByAttribute("input", "type", "submit").get(0).click(); - assertEquals("Update token response is incorrect", + assertEquals("Update token response is incorrect", Messages.ApiTokenProperty_ChangeToken_SuccessHidden(), "

    " + res.getBody().asNormalizedText() + "
    "); } @@ -176,106 +176,106 @@ public void postWithUsernameAndTokenInBasicAuthHeader() throws Exception { @NonNull private WebClient createClientForUser(final String id) throws Exception { User u = User.getById(id, true); - + WebClient wc = j.createWebClient(); wc.withBasicApiToken(u); return wc; } - + @Test @Issue("JENKINS-32776") public void generateNewTokenWithoutName() throws Exception { j.jenkins.setCrumbIssuer(null); j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); - + // user is still able to connect with legacy token User admin = User.getById("admin", true); - + WebClient wc = j.createWebClient(); wc.withBasicCredentials("admin", "admin"); - + GenerateNewTokenResponse token1 = generateNewToken(wc, "admin", ""); assertNotEquals("", token1.tokenName.trim()); - + GenerateNewTokenResponse token2 = generateNewToken(wc, "admin", "New Token"); assertEquals("New Token", token2.tokenName); } - + @Test @LocalData @Issue("JENKINS-32776") public void migrationFromLegacyToken() throws Exception { j.jenkins.setCrumbIssuer(null); - + // user is still able to connect with legacy token User admin = User.getById("admin", false); assertNotNull("Admin user not configured correctly in local data", admin); ApiTokenProperty apiTokenProperty = admin.getProperty(ApiTokenProperty.class); - + WebClient wc = j.createWebClient(); wc.withBasicCredentials("admin", "admin"); checkUserIsConnected(wc); - + // 7be8e81ad5a350fa3f3e2acfae4adb14 String localLegacyToken = apiTokenProperty.getApiTokenInsecure(); wc = j.createWebClient(); wc.withBasicCredentials("admin", localLegacyToken); checkUserIsConnected(wc); - + // can still renew it after (using API) assertEquals(1, apiTokenProperty.getTokenList().size()); apiTokenProperty.changeApiToken(); assertEquals(1, apiTokenProperty.getTokenList().size()); String newLegacyToken = apiTokenProperty.getApiTokenInsecure(); - + // use the new legacy api token wc = j.createWebClient(); wc.withBasicCredentials("admin", newLegacyToken); checkUserIsConnected(wc); - + // but previous one is not more usable wc = j.createWebClient(); wc.withBasicCredentials("admin", localLegacyToken); checkUserIsNotConnected(wc); - + // ===== new system ===== - + // revoke the legacy ApiTokenStore.HashedToken legacyToken = apiTokenProperty.getTokenStore().getLegacyToken(); assertNotNull(legacyToken); String legacyUuid = legacyToken.getUuid(); - + wc = j.createWebClient(); wc.withBasicCredentials("admin", newLegacyToken); revokeToken(wc, "admin", legacyUuid); - + assertEquals(0, apiTokenProperty.getTokenList().size()); - + // check it does not work any more wc = j.createWebClient(); wc.withBasicCredentials("admin", newLegacyToken); checkUserIsNotConnected(wc); - + wc = j.createWebClient(); wc.withBasicCredentials("admin", localLegacyToken); checkUserIsNotConnected(wc); - + // ensure the user can still connect using its username / password wc = j.createWebClient(); wc.withBasicCredentials("admin", "admin"); checkUserIsConnected(wc); - + // generate new token with the new system wc = j.createWebClient(); wc.login("admin", "admin"); GenerateNewTokenResponse newToken = generateNewToken(wc, "admin", "New Token"); - + // use the new one wc = j.createWebClient(); wc.withBasicCredentials("admin", newToken.tokenValue); checkUserIsConnected(wc); } - + private void checkUserIsConnected(WebClient wc) throws Exception { XmlPage xmlPage = wc.goToXml("whoAmI/api/xml"); assertThat(xmlPage, hasXPath("//name", is("admin"))); @@ -283,7 +283,7 @@ private void checkUserIsConnected(WebClient wc) throws Exception { assertThat(xmlPage, hasXPath("//authenticated", is("true"))); assertThat(xmlPage, hasXPath("//authority", is("authenticated"))); } - + private void checkUserIsNotConnected(WebClient wc) throws Exception { try{ wc.goToXml("whoAmI/api/xml"); @@ -293,49 +293,49 @@ private void checkUserIsNotConnected(WebClient wc) throws Exception { assertEquals(401, e.getStatusCode()); } } - + @Test @Issue("JENKINS-32776") public void legacyTokenChange() throws Exception { j.jenkins.setCrumbIssuer(null); j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); - + ApiTokenPropertyConfiguration config = ApiTokenPropertyConfiguration.get(); - + config.setTokenGenerationOnCreationEnabled(true); - + User user = User.getById("user", true); WebClient wc = j.createWebClient(); wc.withBasicCredentials("user", "user"); ApiTokenProperty apiTokenProperty = user.getProperty(ApiTokenProperty.class); - + { // with one legacy token, we can change it using web UI or direct internal call String currentLegacyToken = apiTokenProperty.getApiToken(); assertEquals(1, apiTokenProperty.getTokenList().size()); - + config.setCreationOfLegacyTokenEnabled(true); { // change using web UI changeLegacyToken(wc, "user", true); String newLegacyToken = apiTokenProperty.getApiToken(); assertNotEquals(newLegacyToken, currentLegacyToken); - + // change using internal call apiTokenProperty.changeApiToken(); String newLegacyToken2 = apiTokenProperty.getApiToken(); assertNotEquals(newLegacyToken2, newLegacyToken); assertNotEquals(newLegacyToken2, currentLegacyToken); - + currentLegacyToken = newLegacyToken2; } - + config.setCreationOfLegacyTokenEnabled(false); { // change using web UI changeLegacyToken(wc, "user", true); String newLegacyToken = apiTokenProperty.getApiToken(); assertNotEquals(newLegacyToken, currentLegacyToken); - + // change using internal call apiTokenProperty.changeApiToken(); String newLegacyToken2 = apiTokenProperty.getApiToken(); @@ -345,21 +345,21 @@ public void legacyTokenChange() throws Exception { } { // but without any legacy token, the direct internal call remains but web UI depends on config revokeAllToken(wc, user); - + checkCombinationWithConfigAndMethodForLegacyTokenCreation(config, wc, user); } {// only the legacy token have impact on that capability generateNewToken(wc, "user", "New token"); - + checkCombinationWithConfigAndMethodForLegacyTokenCreation(config, wc, user); } } - + private void checkCombinationWithConfigAndMethodForLegacyTokenCreation( ApiTokenPropertyConfiguration config, WebClient wc, User user ) throws Exception { ApiTokenProperty apiTokenProperty = user.getProperty(ApiTokenProperty.class); - + config.setCreationOfLegacyTokenEnabled(true); { {// change using web UI @@ -368,14 +368,14 @@ private void checkCombinationWithConfigAndMethodForLegacyTokenCreation( assertNotEquals(newLegacyToken, Messages.ApiTokenProperty_ChangeToken_CapabilityNotAllowed()); } revokeLegacyToken(wc, user); - + // always possible changeTokenByDirectCall(apiTokenProperty); revokeLegacyToken(wc, user); } - + revokeAllToken(wc, user); - + config.setCreationOfLegacyTokenEnabled(false); { {// change not possible using web UI @@ -384,27 +384,27 @@ private void checkCombinationWithConfigAndMethodForLegacyTokenCreation( assertEquals(newLegacyToken, Messages.ApiTokenProperty_NoLegacyToken()); } revokeLegacyToken(wc, user); - + // always possible changeTokenByDirectCall(apiTokenProperty); revokeLegacyToken(wc, user); } } - + private void changeTokenByDirectCall(ApiTokenProperty apiTokenProperty) throws Exception { apiTokenProperty.changeApiToken(); String newLegacyToken = apiTokenProperty.getApiToken(); assertNotEquals(newLegacyToken, Messages.ApiTokenProperty_ChangeToken_CapabilityNotAllowed()); } - + private void revokeAllToken(WebClient wc, User user) throws Exception { revokeAllTokenUsingFilter(wc, user, it -> true); } - + private void revokeLegacyToken(WebClient wc, User user) throws Exception { revokeAllTokenUsingFilter(wc, user, ApiTokenStore.HashedToken::isLegacy); } - + private void revokeAllTokenUsingFilter(WebClient wc, User user, Predicate filter) throws Exception { ApiTokenProperty apiTokenProperty = user.getProperty(ApiTokenProperty.class); List uuidList = apiTokenProperty.getTokenStore().getTokenListSortedByName().stream() @@ -415,7 +415,7 @@ private void revokeAllTokenUsingFilter(WebClient wc, User user, Predicate { enableLegacyTokenGenerationOnUserCreation(); configureSecurity(j); - + { JenkinsRule.WebClient wc = j.createWebClient(); // default SecurityListener will save the user when adding the LastGrantedAuthoritiesProperty @@ -77,10 +77,10 @@ public void legacyToken_regularCase() throws Throwable { sessions.then(j -> { User user = User.getById("user1", false); assertNotNull(user); - + JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + { // for invalid token, no effect WebRequest request = new WebRequest(new URL(j.jenkins.getRootUrl() + "whoAmI/api/xml")); request.setAdditionalHeader("Authorization", base64("user1", "invalid-token")); @@ -91,9 +91,9 @@ public void legacyToken_regularCase() throws Throwable { request.setAdditionalHeader("Authorization", base64("user-not-valid", token.get())); assertThat(wc.getPage(request).getWebResponse().getStatusCode(), equalTo(401)); } - + assertNull(User.getById("user-not-valid", false)); - + { // valid user with valid token, ok WebRequest request = new WebRequest(new URL(j.jenkins.getRootUrl() + "whoAmI/api/xml")); request.setAdditionalHeader("Authorization", base64("user1", token.get())); @@ -102,7 +102,7 @@ public void legacyToken_regularCase() throws Throwable { } }); } - + /* * The user is not saved after login without the default SecurityListener#fireAuthenticated */ @@ -113,7 +113,7 @@ public void legacyToken_withoutLastGrantedAuthorities() throws Throwable { sessions.then(j -> { enableLegacyTokenGenerationOnUserCreation(); configureSecurity(j); - + { JenkinsRule.WebClient wc = j.createWebClient(); wc.login("user1"); @@ -125,10 +125,10 @@ public void legacyToken_withoutLastGrantedAuthorities() throws Throwable { sessions.then(j -> { User user = User.getById("user1", false); assertNull(user); - + JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + { // for invalid token, no effect WebRequest request = new WebRequest(new URL(j.jenkins.getRootUrl() + "whoAmI/api/xml")); request.setAdditionalHeader("Authorization", base64("user1", "invalid-token")); @@ -139,10 +139,10 @@ public void legacyToken_withoutLastGrantedAuthorities() throws Throwable { request.setAdditionalHeader("Authorization", base64("user-not-valid", token.get())); assertThat(wc.getPage(request).getWebResponse().getStatusCode(), equalTo(401)); } - + assertNull(User.getById("user1", false)); assertNull(User.getById("user-not-valid", false)); - + { // valid user with valid token, ok WebRequest request = new WebRequest(new URL(j.jenkins.getRootUrl() + "whoAmI/api/xml")); request.setAdditionalHeader("Authorization", base64("user1", token.get())); @@ -155,7 +155,7 @@ public void legacyToken_withoutLastGrantedAuthorities() throws Throwable { assertNull(user); }); } - + @TestExtension("legacyToken_withoutLastGrantedAuthorities") public static class RemoveDefaultSecurityListener extends ExtensionFilter { @Override @@ -163,21 +163,21 @@ public boolean allows(Class type, ExtensionComponent component) { return !SecurityListener.class.isAssignableFrom(type); } } - + private static void enableLegacyTokenGenerationOnUserCreation() throws Exception { ApiTokenPropertyConfiguration apiTokenConfiguration = GlobalConfiguration.all().getInstance(ApiTokenPropertyConfiguration.class); // by default it's false apiTokenConfiguration.setTokenGenerationOnCreationEnabled(true); } - + private static void configureSecurity(JenkinsRule j) throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() .grant(Jenkins.ADMINISTER).everywhere().toEveryone()); - + j.jenkins.save(); } - + private static String base64(String login, String password) { return "Basic " + Base64.getEncoder().encodeToString((login + ":" + password).getBytes(StandardCharsets.UTF_8)); } diff --git a/test/src/test/java/jenkins/security/BasicHeaderProcessorTest.java b/test/src/test/java/jenkins/security/BasicHeaderProcessorTest.java index c097611b22cd..2a8324c5d921 100644 --- a/test/src/test/java/jenkins/security/BasicHeaderProcessorTest.java +++ b/test/src/test/java/jenkins/security/BasicHeaderProcessorTest.java @@ -61,7 +61,7 @@ public void testVariousWaysToCall() throws Exception { // call with API token wc = j.createWebClient(); wc.withBasicApiToken("foo"); - makeRequestAndVerify("foo"); + makeRequestAndVerify("foo"); spySecurityListener.authenticatedCalls.assertLastEventIsAndThenRemoveIt(u -> u.getUsername().equals("foo")); // call with invalid API token @@ -115,7 +115,7 @@ private void makeRequestAndVerify(String expectedLogin) throws IOException, SAXE @Test public void testAuthHeaderCaseInSensitive() throws Exception { ApiTokenTestHelper.enableLegacyBehavior(); - + j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); User foo = User.getOrCreateByIdOrFullName("foo"); wc = j.createWebClient(); diff --git a/test/src/test/java/jenkins/security/RedactSecretJsonInErrorMessageSanitizerHtmlTest.java b/test/src/test/java/jenkins/security/RedactSecretJsonInErrorMessageSanitizerHtmlTest.java index 23240866bf30..d64bc4a2e0db 100644 --- a/test/src/test/java/jenkins/security/RedactSecretJsonInErrorMessageSanitizerHtmlTest.java +++ b/test/src/test/java/jenkins/security/RedactSecretJsonInErrorMessageSanitizerHtmlTest.java @@ -58,43 +58,43 @@ @Restricted(NoExternalUse.class) public class RedactSecretJsonInErrorMessageSanitizerHtmlTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Rule public LoggerRule logging = new LoggerRule(); - + @Test @Issue("SECURITY-765") public void passwordsAreRedacted_andOtherStayTheSame() throws Exception { j.jenkins.setCrumbIssuer(null); TestPassword testPassword = j.jenkins.getExtensionList(RootAction.class).get(TestPassword.class); - + JenkinsRule.WebClient wc = j.createWebClient(); HtmlPage page = wc.goTo("test"); - + String textSimple = "plain-1"; String pwdSimple = "secret-1"; ((HtmlInput) page.getElementById("text-simple")).setValueAttribute(textSimple); ((HtmlInput) page.getElementById("pwd-simple")).setValueAttribute(pwdSimple); - + String textLevelOne = "plain-2"; String pwdLevelOneA = "secret-2"; ((HtmlInput) page.getElementById("text-level-one")).setValueAttribute(textLevelOne); ((HtmlInput) page.getElementById("pwd-level-one-a")).setValueAttribute(pwdLevelOneA); - + HtmlForm form = page.getFormByName("config"); Page formSubmitPage = j.submit(form); assertThat(formSubmitPage.getWebResponse().getStatusCode(), equalTo(200)); - + JSONObject rawJson = testPassword.lastJsonReceived; String rawJsonToString = rawJson.toString(); assertThat(rawJsonToString, containsString(textSimple)); assertThat(rawJsonToString, containsString(pwdSimple)); assertThat(rawJsonToString, containsString(textLevelOne)); assertThat(rawJsonToString, containsString(pwdLevelOneA)); - + assertThat(rawJson.getString(RedactSecretJsonInErrorMessageSanitizer.REDACT_KEY), equalTo("pwd-simple")); assertThat( rawJson.getJSONObject("sub-one").getJSONArray(RedactSecretJsonInErrorMessageSanitizer.REDACT_KEY), @@ -103,7 +103,7 @@ public void passwordsAreRedacted_andOtherStayTheSame() throws Exception { hasItem("pwd-level-one-b") ) ); - + String pwdLevelOneB = "pre-set secret"; // set in Jelly JSONObject redactedJson = RedactSecretJsonInErrorMessageSanitizer.INSTANCE.sanitize(rawJson); String redactedJsonToString = redactedJson.toString(); @@ -114,54 +114,54 @@ public void passwordsAreRedacted_andOtherStayTheSame() throws Exception { assertThat(redactedJsonToString, not(containsString(pwdLevelOneB))); assertThat(redactedJsonToString, containsString(RedactSecretJsonInErrorMessageSanitizer.REDACT_VALUE)); } - + @TestExtension("passwordsAreRedacted_andOtherStayTheSame") public static class TestPassword implements RootAction { - + public JSONObject lastJsonReceived; - + public void doSubmitTest(StaplerRequest req, StaplerResponse res) throws Exception { lastJsonReceived = req.getSubmittedForm(); - + res.setStatus(200); } - + @Override public String getIconFileName() { return null; } - + @Override public String getDisplayName() { return null; } - + @Override public String getUrlName() { return "test"; } } - + @Test @Issue("SECURITY-765") public void checkSanitizationIsApplied_inDescriptor() throws Exception { logging.record("", Level.WARNING).capture(100); - + j.jenkins.setCrumbIssuer(null); - + JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); HtmlPage page = wc.goTo("testDescribable"); String secret = "s3cr3t"; ((HtmlInput) page.getElementById("password")).setValueAttribute(secret); - + HtmlForm form = page.getFormByName("config"); Page formSubmitPage = j.submit(form); assertThat(formSubmitPage.getWebResponse().getContentAsString(), allOf( containsString(RedactSecretJsonInErrorMessageSanitizer.REDACT_VALUE), not(containsString(secret)) )); - + // check the system log also Throwable thrown = logging.getRecords().stream().filter(r -> r.getMessage().contains("Error while serving")).findAny().get().getThrown(); // the exception from Descriptor @@ -169,13 +169,13 @@ public void checkSanitizationIsApplied_inDescriptor() throws Exception { containsString(RedactSecretJsonInErrorMessageSanitizer.REDACT_VALUE), not(containsString(secret)) )); - + // the exception from RequestImpl assertThat(thrown.getCause().getCause().getMessage(), allOf( containsString(RedactSecretJsonInErrorMessageSanitizer.REDACT_VALUE), not(containsString(secret)) )); - + StringWriter buffer = new StringWriter(); thrown.printStackTrace(new PrintWriter(buffer)); String fullStack = buffer.getBuffer().toString(); @@ -184,27 +184,27 @@ public void checkSanitizationIsApplied_inDescriptor() throws Exception { not(containsString(secret)) )); } - + @Test @Issue("SECURITY-765") public void checkSanitizationIsApplied_inStapler() throws Exception { logging.record("", Level.WARNING).capture(100); - + j.jenkins.setCrumbIssuer(null); - + JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); HtmlPage page = wc.goTo("testStapler"); String secret = "s3cr3t"; ((HtmlInput) page.getElementById("password")).setValueAttribute(secret); - + HtmlForm form = page.getFormByName("config"); Page formSubmitPage = j.submit(form); assertThat(formSubmitPage.getWebResponse().getContentAsString(), allOf( containsString(RedactSecretJsonInErrorMessageSanitizer.REDACT_VALUE), not(containsString(secret)) )); - + // check the system log also Throwable thrown = logging.getRecords().stream().filter(r -> r.getMessage().contains("Error while serving")).findAny().get().getThrown(); // the exception from RequestImpl @@ -212,7 +212,7 @@ public void checkSanitizationIsApplied_inStapler() throws Exception { containsString(RedactSecretJsonInErrorMessageSanitizer.REDACT_VALUE), not(containsString(secret)) )); - + StringWriter buffer = new StringWriter(); thrown.printStackTrace(new PrintWriter(buffer)); String fullStack = buffer.getBuffer().toString(); @@ -221,74 +221,74 @@ public void checkSanitizationIsApplied_inStapler() throws Exception { not(containsString(secret)) )); } - + public static class TestDescribable implements Describable { - + @DataBoundConstructor public TestDescribable(Secret password) { throw new IllegalArgumentException("Try to steal my password"); } - + @Override public DescriptorImpl getDescriptor() { return Jenkins.get().getDescriptorByType(TestDescribable.DescriptorImpl.class); } - + @TestExtension({ "checkSanitizationIsApplied_inStapler", "checkSanitizationIsApplied_inDescriptor" }) public static final class DescriptorImpl extends Descriptor { - + } } - + @TestExtension("checkSanitizationIsApplied_inDescriptor") public static class TestDescribablePage implements RootAction { - + public TestDescribable testDescribable; - + @POST public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws Exception { Jenkins.get().getDescriptorOrDie(TestDescribable.class).newInstance(req, req.getSubmittedForm()); } - + @Override public String getIconFileName() { return null; } - + @Override public String getDisplayName() { return null; } - + @Override public String getUrlName() { return "testDescribable"; } } - + @TestExtension("checkSanitizationIsApplied_inStapler") public static class TestStaplerPage implements RootAction { - + public TestDescribable testDescribable; - + @POST public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws Exception { req.bindJSON(TestDescribable.class, req.getSubmittedForm()); } - + @Override public String getIconFileName() { return null; } - + @Override public String getDisplayName() { return null; } - + @Override public String getUrlName() { return "testStapler"; diff --git a/test/src/test/java/jenkins/security/RekeySecretAdminMonitorTest.java b/test/src/test/java/jenkins/security/RekeySecretAdminMonitorTest.java index d0a2397fd3ef..9bb9e5d659c6 100644 --- a/test/src/test/java/jenkins/security/RekeySecretAdminMonitorTest.java +++ b/test/src/test/java/jenkins/security/RekeySecretAdminMonitorTest.java @@ -149,7 +149,7 @@ private HtmlButton getButton(HtmlForm form, int index) { if (index > 0) { buttonStream = buttonStream.skip(index); } - + return buttonStream .findFirst() .orElse(null); diff --git a/test/src/test/java/jenkins/security/Security177Test.java b/test/src/test/java/jenkins/security/Security177Test.java index e5647cbada9e..eaa2e0623619 100644 --- a/test/src/test/java/jenkins/security/Security177Test.java +++ b/test/src/test/java/jenkins/security/Security177Test.java @@ -17,7 +17,7 @@ public class Security177Test { @Rule public JenkinsRule jenkins = new JenkinsRule(); - + @Test public void nosniff() throws Exception { WebClient wc = jenkins.createWebClient() diff --git a/test/src/test/java/jenkins/security/Security637Test.java b/test/src/test/java/jenkins/security/Security637Test.java index 4a94118708f3..327ae6dce397 100644 --- a/test/src/test/java/jenkins/security/Security637Test.java +++ b/test/src/test/java/jenkins/security/Security637Test.java @@ -53,10 +53,10 @@ import org.jvnet.hudson.test.TestExtension; public class Security637Test { - + @Rule public JenkinsSessionRule sessions = new JenkinsSessionRule(); - + @Test @Issue("SECURITY-637") public void urlSafeDeserialization_handler_inSameJVMRemotingContext() throws Throwable { @@ -64,19 +64,19 @@ public void urlSafeDeserialization_handler_inSameJVMRemotingContext() throws Thr DumbSlave slave = j.createOnlineSlave(); String unsafeHandlerClassName = slave.getChannel().call(new URLHandlerCallable(new URL("https://www.google.com/"))); assertThat(unsafeHandlerClassName, containsString("SafeURLStreamHandler")); - + String safeHandlerClassName = slave.getChannel().call(new URLHandlerCallable(new URL("file", null, -1, "", null))); assertThat(safeHandlerClassName, not(containsString("SafeURLStreamHandler"))); }); } - + private static class URLHandlerCallable extends MasterToSlaveCallable { private URL url; - + URLHandlerCallable(URL url) { this.url = url; } - + @Override public String call() throws Exception { Field handlerField = URL.class.getDeclaredField("handler"); @@ -98,14 +98,14 @@ public void urlDnsEquivalence() throws Throwable { ); }); } - + @Ignore("TODO these map to different IPs now") @Test @Issue("SECURITY-637") public void urlSafeDeserialization_urlBuiltInAgent_inSameJVMRemotingContext() throws Throwable { sessions.then(j -> { DumbSlave slave = j.createOnlineSlave(); - + // we bypass the standard equals method that resolve the hostname assertThat( slave.getChannel().call(new URLBuilderCallable("https://jenkins.io")), @@ -115,27 +115,27 @@ public void urlSafeDeserialization_urlBuiltInAgent_inSameJVMRemotingContext() th ); }); } - + private static class URLBuilderCallable extends MasterToSlaveCallable { private String url; - + URLBuilderCallable(String url) { this.url = url; } - + @Override public URL call() throws Exception { return new URL(url); } } - + @Ignore("TODO these map to different IPs now") @Test @Issue("SECURITY-637") public void urlSafeDeserialization_urlBuiltInMaster_inSameJVMRemotingContext() throws Throwable { sessions.then(j -> { DumbSlave slave = j.createOnlineSlave(); - + // we bypass the standard equals method that resolve the hostname assertThat( slave.getChannel().call(new URLTransferCallable(new URL("https://jenkins.io"))), @@ -143,7 +143,7 @@ public void urlSafeDeserialization_urlBuiltInMaster_inSameJVMRemotingContext() t slave.getChannel().call(new URLTransferCallable(new URL("https://www.jenkins.io"))) )) ); - + // due to the DNS resolution they are equal assertEquals( new URL("https://jenkins.io"), @@ -151,21 +151,21 @@ public void urlSafeDeserialization_urlBuiltInMaster_inSameJVMRemotingContext() t ); }); } - + // the URL is serialized / deserialized twice, master => agent and then agent => master private static class URLTransferCallable extends MasterToSlaveCallable { private URL url; - + URLTransferCallable(URL url) { this.url = url; } - + @Override public URL call() throws Exception { return url; } } - + @Test @Issue("SECURITY-637") public void urlSafeDeserialization_inXStreamContext() throws Throwable { @@ -178,17 +178,17 @@ public void urlSafeDeserialization_inXStreamContext() throws Throwable { new URL("https", null, -1, "", null) ); project.addProperty(URLJobProperty); - + project.save(); }); - + sessions.then(j -> { FreeStyleProject project = j.jenkins.getItemByFullName("project-with-url", FreeStyleProject.class); assertNotNull(project); - + Field handlerField = URL.class.getDeclaredField("handler"); handlerField.setAccessible(true); - + URLJobProperty urlJobProperty = project.getProperty(URLJobProperty.class); for (URL url : urlJobProperty.urlSet) { URLStreamHandler handler = (URLStreamHandler) handlerField.get(url); @@ -200,21 +200,21 @@ public void urlSafeDeserialization_inXStreamContext() throws Throwable { } }); } - + public static class URLJobProperty extends JobProperty { - + private Set urlSet; - + public URLJobProperty(URL... urls) { this.urlSet = new HashSet<>(); Collections.addAll(urlSet, urls); } - + @Override public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { return true; } - + @TestExtension("urlSafeDeserialization_inXStreamContext") public static class DescriptorImpl extends JobPropertyDescriptor {} } diff --git a/test/src/test/java/jenkins/security/SecurityContextExecutorServiceTest.java b/test/src/test/java/jenkins/security/SecurityContextExecutorServiceTest.java index 0ec24738380f..65c5a2056c7f 100644 --- a/test/src/test/java/jenkins/security/SecurityContextExecutorServiceTest.java +++ b/test/src/test/java/jenkins/security/SecurityContextExecutorServiceTest.java @@ -71,7 +71,7 @@ public void before() throws Throwable { SecurityContextHolder.clearContext(); nullContext = SecurityContextHolder.getContext(); - // Create a wrapped service + // Create a wrapped service wrappedService = new SecurityContextExecutorService(service); } }; diff --git a/test/src/test/java/jenkins/security/SpySecurityListener.java b/test/src/test/java/jenkins/security/SpySecurityListener.java index ce4a543b5610..45296d758fca 100644 --- a/test/src/test/java/jenkins/security/SpySecurityListener.java +++ b/test/src/test/java/jenkins/security/SpySecurityListener.java @@ -45,7 +45,7 @@ public abstract class SpySecurityListener extends SecurityListener { public final EventQueue loggedInCalls = new EventQueue<>(); public final EventQueue failedToLogInCalls = new EventQueue<>(); public final EventQueue loggedOutCalls = new EventQueue<>(); - + public void clearPreviousCalls(){ this.authenticatedCalls.clear(); this.failedToAuthenticateCalls.clear(); @@ -53,31 +53,31 @@ public void clearPreviousCalls(){ this.failedToLogInCalls.clear(); this.loggedOutCalls.clear(); } - + @Override protected void authenticated2(@NonNull UserDetails details) { this.authenticatedCalls.add(details); } - + @Override protected void failedToAuthenticate(@NonNull String username) { this.failedToAuthenticateCalls.add(username); } - + @Override protected void loggedIn(@NonNull String username) { this.loggedInCalls.add(username); } - + @Override protected void failedToLogIn(@NonNull String username) { this.failedToLogInCalls.add(username); } - + @Override protected void loggedOut(@NonNull String username) { this.loggedOutCalls.add(username); - + } public static class EventQueue { diff --git a/test/src/test/java/jenkins/security/apitoken/ApiTokenPropertyConfigurationTest.java b/test/src/test/java/jenkins/security/apitoken/ApiTokenPropertyConfigurationTest.java index 7dc91b015c9f..c4ff818f6835 100644 --- a/test/src/test/java/jenkins/security/apitoken/ApiTokenPropertyConfigurationTest.java +++ b/test/src/test/java/jenkins/security/apitoken/ApiTokenPropertyConfigurationTest.java @@ -37,33 +37,33 @@ import org.jvnet.hudson.test.JenkinsRule; public class ApiTokenPropertyConfigurationTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Test @Issue("JENKINS-32776") public void newUserTokenConfiguration() throws Exception { ApiTokenPropertyConfiguration config = ApiTokenPropertyConfiguration.get(); - + config.setTokenGenerationOnCreationEnabled(true); { User userWith = User.getById("userWith", true); ApiTokenProperty withToken = userWith.getProperty(ApiTokenProperty.class); assertTrue(withToken.hasLegacyToken()); assertEquals(1, withToken.getTokenList().size()); - + String tokenValue = withToken.getApiToken(); Assert.assertNotEquals(Messages.ApiTokenProperty_NoLegacyToken(), tokenValue); } - + config.setTokenGenerationOnCreationEnabled(false); { User userWithout = User.getById("userWithout", true); ApiTokenProperty withoutToken = userWithout.getProperty(ApiTokenProperty.class); assertFalse(withoutToken.hasLegacyToken()); assertEquals(0, withoutToken.getTokenList().size()); - + String tokenValue = withoutToken.getApiToken(); Assert.assertEquals(Messages.ApiTokenProperty_NoLegacyToken(), tokenValue); } diff --git a/test/src/test/java/jenkins/security/apitoken/ApiTokenStatsRestartTest.java b/test/src/test/java/jenkins/security/apitoken/ApiTokenStatsRestartTest.java index 62051f2e448c..df435a6f4318 100644 --- a/test/src/test/java/jenkins/security/apitoken/ApiTokenStatsRestartTest.java +++ b/test/src/test/java/jenkins/security/apitoken/ApiTokenStatsRestartTest.java @@ -58,10 +58,10 @@ @For(ApiTokenStats.class) public class ApiTokenStatsRestartTest { - + @Rule public JenkinsSessionRule sessions = new JenkinsSessionRule(); - + @Test @Issue("SECURITY-1072") public void roundtripWithRestart() throws Throwable { @@ -69,11 +69,11 @@ public void roundtripWithRestart() throws Throwable { AtomicReference tokenUuid = new AtomicReference<>(); String TOKEN_NAME = "New Token Name"; int NUM_CALL_WITH_TOKEN = 5; - + sessions.then(j -> { j.jenkins.setCrumbIssuer(null); j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); - + User u = User.getById("foo", true); ApiTokenProperty t = u.getProperty(ApiTokenProperty.class); @@ -119,36 +119,36 @@ public void roundtripWithRestart() throws Throwable { File apiTokenStatsFile = new File(u.getUserFolder(), "apiTokenStats.xml"); assertTrue("apiTokenStats.xml file should exist", apiTokenStatsFile.exists()); }); - + sessions.then(j -> { j.jenkins.setCrumbIssuer(null); - + User u = User.getById("foo", false); assertNotNull(u); - + WebClient wc = j.createWebClient().login(u.getId()); checkUserIsConnected(wc, u.getId()); - + HtmlPage config = wc.goTo(u.getUrl() + "/configure"); assertEquals(200, config.getWebResponse().getStatusCode()); assertThat(config.getWebResponse().getContentAsString(), containsString(tokenUuid.get())); assertThat(config.getWebResponse().getContentAsString(), containsString(TOKEN_NAME)); HtmlSpan useCounterSpan = config.getDocumentElement().getOneHtmlElementByAttribute("span", "class", "token-use-counter"); assertThat(useCounterSpan.getTextContent(), containsString("" + NUM_CALL_WITH_TOKEN)); - + revokeToken(j, wc, u.getId(), tokenUuid.get()); - + // token is no more valid WebClient restWc = j.createWebClient().withBasicCredentials(u.getId(), tokenValue.get()); checkUserIsNotConnected(restWc); - + HtmlPage configWithoutToken = wc.goTo(u.getUrl() + "/configure"); assertEquals(200, configWithoutToken.getWebResponse().getStatusCode()); assertThat(configWithoutToken.getWebResponse().getContentAsString(), not(containsString(tokenUuid.get()))); assertThat(configWithoutToken.getWebResponse().getContentAsString(), not(containsString(TOKEN_NAME))); }); } - + private static void checkUserIsConnected(WebClient wc, String username) throws Exception { XmlPage xmlPage = wc.goToXml("whoAmI/api/xml"); assertThat(xmlPage, hasXPath("//name", is(username))); @@ -156,7 +156,7 @@ private static void checkUserIsConnected(WebClient wc, String username) throws E assertThat(xmlPage, hasXPath("//authenticated", is("true"))); assertThat(xmlPage, hasXPath("//authority", is("authenticated"))); } - + private static void checkUserIsNotConnected(WebClient wc) throws Exception { try { wc.goToXml("whoAmI/api/xml"); @@ -165,7 +165,7 @@ private static void checkUserIsNotConnected(WebClient wc) throws Exception { assertEquals(401, e.getStatusCode()); } } - + private static void revokeToken(JenkinsRule j, WebClient wc, String login, String tokenUuid) throws Exception { WebRequest request = new WebRequest( new URL(j.getURL(), "user/" + login + "/descriptorByName/" + ApiTokenProperty.class.getName() + "/revoke/?tokenUuid=" + tokenUuid), diff --git a/test/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java b/test/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java index 6db084b82445..784b07a8b2b8 100644 --- a/test/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java +++ b/test/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java @@ -51,30 +51,30 @@ import org.jvnet.hudson.test.JenkinsRule.WebClient; public class ApiTokenStatsTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Test public void roundtrip() throws Exception { j.jenkins.setCrumbIssuer(null); j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); User u = User.getById("foo", true); - + ApiTokenProperty t = u.getProperty(ApiTokenProperty.class); assertNotNull(t.getTokenStore()); assertNotNull(t.getTokenStats()); - + // test the authentication via Token WebClient wc = j.createWebClient() .withBasicCredentials(u.getId()) .withThrowExceptionOnFailingStatusCode(false); - + final String TOKEN_NAME = "New Token Name"; - + WebRequest request = new WebRequest(new URL(j.getURL() + "user/" + u.getId() + "/descriptorByName/" + ApiTokenProperty.class.getName() + "/generateNewToken"), HttpMethod.POST); request.setRequestParameters(Collections.singletonList(new NameValuePair("newTokenName", TOKEN_NAME))); - + Page page = wc.getPage(request); assertEquals(200, page.getWebResponse().getStatusCode()); String responseContent = page.getWebResponse().getContentAsString(); @@ -83,39 +83,39 @@ public void roundtrip() throws Exception { String tokenName = jsonData.getString("tokenName"); String tokenValue = jsonData.getString("tokenValue"); String tokenUuid = jsonData.getString("tokenUuid"); - + assertEquals(TOKEN_NAME, tokenName); - + WebClient restWc = j.createWebClient().withBasicCredentials(u.getId(), tokenValue); checkUserIsConnected(restWc, u.getId()); - + HtmlPage config = wc.goTo(u.getUrl() + "/configure"); assertEquals(200, config.getWebResponse().getStatusCode()); assertThat(config.getWebResponse().getContentAsString(), containsString(tokenUuid)); assertThat(config.getWebResponse().getContentAsString(), containsString(tokenName)); - + final int NUM_CALL_WITH_TOKEN = 5; // one is already done with checkUserIsConnected for (int i = 1; i < NUM_CALL_WITH_TOKEN; i++) { restWc.goToXml("whoAmI/api/xml"); } - + HtmlPage configWithStats = wc.goTo(u.getUrl() + "/configure"); assertEquals(200, configWithStats.getWebResponse().getStatusCode()); HtmlSpan useCounterSpan = configWithStats.getDocumentElement().getOneHtmlElementByAttribute("span", "class", "token-use-counter"); assertThat(useCounterSpan.getTextContent(), containsString("" + NUM_CALL_WITH_TOKEN)); - + revokeToken(wc, u.getId(), tokenUuid); - + // token is no more valid checkUserIsNotConnected(restWc); - + HtmlPage configWithoutToken = wc.goTo(u.getUrl() + "/configure"); assertEquals(200, configWithoutToken.getWebResponse().getStatusCode()); assertThat(configWithoutToken.getWebResponse().getContentAsString(), not(containsString(tokenUuid))); assertThat(configWithoutToken.getWebResponse().getContentAsString(), not(containsString(tokenName))); } - + private void checkUserIsConnected(WebClient wc, String username) throws Exception { XmlPage xmlPage = wc.goToXml("whoAmI/api/xml"); assertThat(xmlPage, hasXPath("//name", is(username))); @@ -123,7 +123,7 @@ private void checkUserIsConnected(WebClient wc, String username) throws Exceptio assertThat(xmlPage, hasXPath("//authenticated", is("true"))); assertThat(xmlPage, hasXPath("//authority", is("authenticated"))); } - + private void checkUserIsNotConnected(WebClient wc) throws Exception { try { wc.goToXml("whoAmI/api/xml"); @@ -132,7 +132,7 @@ private void checkUserIsNotConnected(WebClient wc) throws Exception { assertEquals(401, e.getStatusCode()); } } - + private void revokeToken(WebClient wc, String login, String tokenUuid) throws Exception { WebRequest request = new WebRequest( new URL(j.getURL(), "user/" + login + "/descriptorByName/" + ApiTokenProperty.class.getName() + "/revoke/?tokenUuid=" + tokenUuid), diff --git a/test/src/test/java/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitorTest.java b/test/src/test/java/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitorTest.java index 4d31676f9ab6..a262c4f4d15d 100644 --- a/test/src/test/java/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitorTest.java +++ b/test/src/test/java/jenkins/security/apitoken/LegacyApiTokenAdministrativeMonitorTest.java @@ -48,68 +48,68 @@ import org.jvnet.hudson.test.JenkinsRule; public class LegacyApiTokenAdministrativeMonitorTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + private enum SelectFilter { ALL(0), ONLY_FRESH(1), ONLY_RECENT(2); - + int index; - + SelectFilter(int index) { this.index = index; } } - + @Test public void isActive() throws Exception { ApiTokenPropertyConfiguration config = ApiTokenPropertyConfiguration.get(); config.setCreationOfLegacyTokenEnabled(true); config.setTokenGenerationOnCreationEnabled(false); - + // user created without legacy token User user = User.getById("user", true); ApiTokenProperty apiTokenProperty = user.getProperty(ApiTokenProperty.class); assertFalse(apiTokenProperty.hasLegacyToken()); - + LegacyApiTokenAdministrativeMonitor monitor = j.jenkins.getExtensionList(AdministrativeMonitor.class).get(LegacyApiTokenAdministrativeMonitor.class); assertFalse(monitor.isActivated()); - + TokenUuidAndPlainValue tokenInfo = apiTokenProperty.getTokenStore().generateNewToken("Not Legacy"); // "new" token does not trigger the monitor assertFalse(monitor.isActivated()); - + apiTokenProperty.getTokenStore().revokeToken(tokenInfo.tokenUuid); assertFalse(monitor.isActivated()); - + apiTokenProperty.changeApiToken(); assertTrue(monitor.isActivated()); } - + @Test @Issue("JENKINS-52441") public void takeCareOfUserWithIdNull() throws Exception { ApiTokenPropertyConfiguration config = ApiTokenPropertyConfiguration.get(); config.setCreationOfLegacyTokenEnabled(true); config.setTokenGenerationOnCreationEnabled(false); - + // user created without legacy token User user = User.getById("null", true); ApiTokenProperty apiTokenProperty = user.getProperty(ApiTokenProperty.class); assertFalse(apiTokenProperty.hasLegacyToken()); - + LegacyApiTokenAdministrativeMonitor monitor = j.jenkins.getExtensionList(AdministrativeMonitor.class).get(LegacyApiTokenAdministrativeMonitor.class); assertFalse(monitor.isActivated()); - + apiTokenProperty.changeApiToken(); assertTrue(monitor.isActivated()); - + {//revoke the legacy token JenkinsRule.WebClient wc = j.createWebClient(); - + HtmlPage page = wc.goTo(monitor.getUrl() + "/manage"); {// select all (only one user normally) HtmlAnchor filterAll = getFilterByIndex(page, SelectFilter.ALL); @@ -119,25 +119,25 @@ public void takeCareOfUserWithIdNull() throws Exception { HtmlButton revokeSelected = getRevokeSelected(page); HtmlElementUtil.click(revokeSelected); } - + assertFalse(monitor.isActivated()); } - + @Test public void listOfUserWithLegacyTokenIsCorrect() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); - + ApiTokenPropertyConfiguration config = ApiTokenPropertyConfiguration.get(); config.setCreationOfLegacyTokenEnabled(true); config.setTokenGenerationOnCreationEnabled(false); - + LegacyApiTokenAdministrativeMonitor monitor = j.jenkins.getExtensionList(AdministrativeMonitor.class).get(LegacyApiTokenAdministrativeMonitor.class); JenkinsRule.WebClient wc = j.createWebClient(); - + int numToken = 0; int numFreshToken = 0; int numRecentToken = 0; - + {// no user checkUserWithLegacyTokenListIsEmpty(wc, monitor); } @@ -145,72 +145,72 @@ public void listOfUserWithLegacyTokenIsCorrect() throws Exception { User user = User.getById("user", true); ApiTokenProperty apiTokenProperty = user.getProperty(ApiTokenProperty.class); assertFalse(apiTokenProperty.hasLegacyToken()); - + checkUserWithLegacyTokenListIsEmpty(wc, monitor); } {// with user with token but without legacy token User user = User.getById("user", true); ApiTokenProperty apiTokenProperty = user.getProperty(ApiTokenProperty.class); assertFalse(apiTokenProperty.hasLegacyToken()); - + apiTokenProperty.getTokenStore().generateNewToken("Not legacy"); - + checkUserWithLegacyTokenListIsEmpty(wc, monitor); checkUserWithLegacyTokenListHasSizeOf(wc, monitor, numToken, numFreshToken, numRecentToken); } {// one user with just legacy token createUserWithToken(true, false, false); - + numToken++; - + checkUserWithLegacyTokenListHasSizeOf(wc, monitor, numToken, numFreshToken, numRecentToken); } {// one user with a fresh token // fresh = created after the last use of the legacy token (or its creation) createUserWithToken(true, true, false); - + numToken++; numFreshToken++; - + checkUserWithLegacyTokenListHasSizeOf(wc, monitor, numToken, numFreshToken, numRecentToken); } {// one user with a recent token (that is not fresh) // recent = last use after the last use of the legacy token (or its creation) createUserWithToken(true, false, true); - + numToken++; numRecentToken++; - + checkUserWithLegacyTokenListHasSizeOf(wc, monitor, numToken, numFreshToken, numRecentToken); } {// one user with a fresh + recent token createUserWithToken(true, true, true); - + numToken++; numFreshToken++; numRecentToken++; - + checkUserWithLegacyTokenListHasSizeOf(wc, monitor, numToken, numFreshToken, numRecentToken); } } - + @Test public void monitorManagePageFilterAreWorking() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); - + ApiTokenPropertyConfiguration config = ApiTokenPropertyConfiguration.get(); config.setCreationOfLegacyTokenEnabled(true); config.setTokenGenerationOnCreationEnabled(false); - + // create 1 user with legacy, 2 with fresh, 3 with recent and 4 with fresh+recent prepareUsersForFilters(); - + LegacyApiTokenAdministrativeMonitor monitor = j.jenkins.getExtensionList(AdministrativeMonitor.class).get(LegacyApiTokenAdministrativeMonitor.class); JenkinsRule.WebClient wc = j.createWebClient(); - + HtmlPage page = wc.goTo(monitor.getUrl() + "/manage"); checkUserWithLegacyTokenListHasSizeOf(page, 1 + 2 + 3 + 4, 2 + 4, 3 + 4); - + HtmlElement document = page.getDocumentElement(); HtmlElement filterDiv = document.getOneHtmlElementByAttribute("div", "class", "selection-panel"); DomNodeList filters = filterDiv.getElementsByTagName("a"); @@ -218,88 +218,88 @@ public void monitorManagePageFilterAreWorking() throws Exception { HtmlAnchor filterAll = (HtmlAnchor) filters.get(0); HtmlAnchor filterOnlyFresh = (HtmlAnchor) filters.get(1); HtmlAnchor filterOnlyRecent = (HtmlAnchor) filters.get(2); - + { // test just the filterAll checkNumberOfSelectedTr(document, 0); - + HtmlElementUtil.click(filterAll); checkNumberOfSelectedTr(document, 1 + 2 + 3 + 4); - + HtmlElementUtil.click(filterAll); checkNumberOfSelectedTr(document, 0); } { // test just the filterOnlyFresh HtmlElementUtil.click(filterOnlyFresh); checkNumberOfSelectedTr(document, 2 + 4); - + HtmlElementUtil.click(filterOnlyFresh); checkNumberOfSelectedTr(document, 0); } { // test just the filterOnlyRecent HtmlElementUtil.click(filterOnlyRecent); checkNumberOfSelectedTr(document, 3 + 4); - + HtmlElementUtil.click(filterOnlyRecent); checkNumberOfSelectedTr(document, 0); } { // test interaction HtmlElementUtil.click(filterOnlyFresh); checkNumberOfSelectedTr(document, 2 + 4); - + // the 4 (recent+fresh) are still selected HtmlElementUtil.click(filterOnlyRecent); checkNumberOfSelectedTr(document, 3 + 4); - + HtmlElementUtil.click(filterAll); checkNumberOfSelectedTr(document, 1 + 2 + 3 + 4); } } - + private void prepareUsersForFilters() throws Exception { // 1 user with just legacy token createUserWithToken(true, false, false); - + // 2 users fresh but not recent createUserWithToken(true, true, false); createUserWithToken(true, true, false); - + // 3 users recent but not fresh createUserWithToken(true, false, true); createUserWithToken(true, false, true); createUserWithToken(true, false, true); - + // 4 users fresh and recent createUserWithToken(true, true, true); createUserWithToken(true, true, true); createUserWithToken(true, true, true); createUserWithToken(true, true, true); } - + private void checkNumberOfSelectedTr(HtmlElement document, int expectedCount) { DomNodeList trList = document.getElementsByTagName("tr"); long amount = trList.stream().filter(htmlElement -> htmlElement.getAttribute("class").contains("selected")).count(); assertEquals(expectedCount, amount); } - + @Test public void monitorManagePageCanRevokeToken() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); - + ApiTokenPropertyConfiguration config = ApiTokenPropertyConfiguration.get(); config.setCreationOfLegacyTokenEnabled(true); config.setTokenGenerationOnCreationEnabled(false); - + // create 1 user with legacy, 2 with fresh, 3 with recent and 4 with fresh+recent prepareUsersForFilters(); - + LegacyApiTokenAdministrativeMonitor monitor = j.jenkins.getExtensionList(AdministrativeMonitor.class).get(LegacyApiTokenAdministrativeMonitor.class); assertTrue(monitor.isActivated()); - + JenkinsRule.WebClient wc = j.createWebClient(); - + HtmlPage page = wc.goTo(monitor.getUrl() + "/manage"); checkUserWithLegacyTokenListHasSizeOf(page, 1 + 2 + 3 + 4, 2 + 4, 3 + 4); - + {// select 2 HtmlAnchor filterOnlyFresh = getFilterByIndex(page, SelectFilter.ONLY_FRESH); HtmlElementUtil.click(filterOnlyFresh); @@ -307,10 +307,10 @@ public void monitorManagePageCanRevokeToken() throws Exception { // revoke them HtmlButton revokeSelected = getRevokeSelected(page); HtmlElementUtil.click(revokeSelected); - + HtmlPage newPage = checkUserWithLegacyTokenListHasSizeOf(wc, monitor, 1 + 3, 0, 3); assertTrue(monitor.isActivated()); - + {// select 1 + 3 HtmlAnchor filterAll = getFilterByIndex(newPage, SelectFilter.ALL); HtmlElementUtil.click(filterAll); @@ -321,31 +321,31 @@ public void monitorManagePageCanRevokeToken() throws Exception { checkUserWithLegacyTokenListHasSizeOf(wc, monitor, 0, 0, 0); assertFalse(monitor.isActivated()); } - + private HtmlAnchor getFilterByIndex(HtmlPage page, SelectFilter selectFilter) { HtmlElement document = page.getDocumentElement(); HtmlDivision filterDiv = document.getOneHtmlElementByAttribute("div", "class", "selection-panel"); DomNodeList filters = filterDiv.getElementsByTagName("a"); assertEquals(3, filters.size()); - + HtmlAnchor filter = (HtmlAnchor) filters.get(selectFilter.index); assertNotNull(filter); return filter; } - + private HtmlButton getRevokeSelected(HtmlPage page) { HtmlElement document = page.getDocumentElement(); HtmlButton revokeSelected = document.getOneHtmlElementByAttribute("button", "class", "action-revoke-selected"); assertNotNull(revokeSelected); return revokeSelected; } - + private void checkUserWithLegacyTokenListIsEmpty(JenkinsRule.WebClient wc, LegacyApiTokenAdministrativeMonitor monitor) throws Exception { HtmlPage page = wc.goTo(monitor.getUrl() + "/manage"); String pageContent = page.getWebResponse().getContentAsString(); assertThat(pageContent, Matchers.containsString("no-token-line")); } - + private HtmlPage checkUserWithLegacyTokenListHasSizeOf( JenkinsRule.WebClient wc, LegacyApiTokenAdministrativeMonitor monitor, int countOfToken, int countOfFreshToken, int countOfRecentToken) throws Exception { @@ -353,68 +353,68 @@ private HtmlPage checkUserWithLegacyTokenListHasSizeOf( checkUserWithLegacyTokenListHasSizeOf(page, countOfToken, countOfFreshToken, countOfRecentToken); return page; } - + private void checkUserWithLegacyTokenListHasSizeOf( Page page, int countOfToken, int countOfFreshToken, int countOfRecentToken) throws Exception { String pageContent = page.getWebResponse().getContentAsString(); - + int actualCountOfToken = StringUtils.countMatches(pageContent, "token-to-revoke"); assertEquals(countOfToken, actualCountOfToken); - + int actualCountOfFreshToken = StringUtils.countMatches(pageContent, "fresh-token"); assertEquals(countOfFreshToken, actualCountOfFreshToken); - + int actualCountOfRecentToken = StringUtils.countMatches(pageContent, "recent-token"); assertEquals(countOfRecentToken, actualCountOfRecentToken); } - + private void simulateUseOfLegacyToken(User user) throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); wc.withBasicCredentials(user.getId(), user.getProperty(ApiTokenProperty.class).getApiToken()); - + wc.goTo("whoAmI/api/xml", null); } - + private void simulateUseOfToken(User user, String tokenPlainValue) throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); wc.withBasicCredentials(user.getId(), tokenPlainValue); - + wc.goTo("whoAmI/api/xml", null); } - + private int nextId = 0; - + private void createUserWithToken(boolean legacy, boolean fresh, boolean recent) throws Exception { User user = User.getById(String.format("user %b %b %b %d", legacy, fresh, recent, nextId++), true); if (!legacy) { return; } - + ApiTokenProperty apiTokenProperty = user.getProperty(ApiTokenProperty.class); apiTokenProperty.changeApiToken(); - + if (fresh) { if (recent) { simulateUseOfLegacyToken(user); Thread.sleep(1); - + TokenUuidAndPlainValue tokenInfo = apiTokenProperty.getTokenStore().generateNewToken("Fresh and recent token"); simulateUseOfToken(user, tokenInfo.plainValue); } else { simulateUseOfLegacyToken(user); Thread.sleep(1); - + apiTokenProperty.getTokenStore().generateNewToken("Fresh token"); } } else { if (recent) { TokenUuidAndPlainValue tokenInfo = apiTokenProperty.getTokenStore().generateNewToken("Recent token"); Thread.sleep(1); - + simulateUseOfLegacyToken(user); Thread.sleep(1); - + simulateUseOfToken(user, tokenInfo.plainValue); } //else: no other token to generate diff --git a/test/src/test/java/jenkins/security/csrf/CSRFAdministrativeMonitorTest.java b/test/src/test/java/jenkins/security/csrf/CSRFAdministrativeMonitorTest.java index bb930300a3d5..c8060c54f82b 100644 --- a/test/src/test/java/jenkins/security/csrf/CSRFAdministrativeMonitorTest.java +++ b/test/src/test/java/jenkins/security/csrf/CSRFAdministrativeMonitorTest.java @@ -34,15 +34,15 @@ import org.jvnet.hudson.test.JenkinsRule; public class CSRFAdministrativeMonitorTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Test @Issue("JENKINS-47372") public void testWithoutIssuer() { j.jenkins.setCrumbIssuer(null); - + CSRFAdministrativeMonitor monitor = j.jenkins.getExtensionList(AdministrativeMonitor.class).get(CSRFAdministrativeMonitor.class); assertTrue("Monitor must not be activated", monitor.isActivated()); } @@ -51,7 +51,7 @@ public void testWithoutIssuer() { @Issue("JENKINS-47372") public void testWithIssuer() { j.jenkins.setCrumbIssuer(new DefaultCrumbIssuer(false)); - + CSRFAdministrativeMonitor monitor = j.jenkins.getExtensionList(AdministrativeMonitor.class).get(CSRFAdministrativeMonitor.class); assertFalse("Monitor must be activated", monitor.isActivated()); } diff --git a/test/src/test/java/jenkins/security/seed/UserSeedChangeListenerTest.java b/test/src/test/java/jenkins/security/seed/UserSeedChangeListenerTest.java index 38d992a08dcf..16604a2c1c9a 100644 --- a/test/src/test/java/jenkins/security/seed/UserSeedChangeListenerTest.java +++ b/test/src/test/java/jenkins/security/seed/UserSeedChangeListenerTest.java @@ -49,10 +49,10 @@ public void onProgrammaticUserSeedChange_listenerTriggered() throws Exception { String userId = "alice"; User alice = User.getById(userId, true); assertNull(testListener.lastUserIdReceived); - + UserSeedProperty userSeed = alice.getProperty(UserSeedProperty.class); assertNull(testListener.lastUserIdReceived); - + userSeed.renewSeed(); assertThat(testListener.lastUserIdReceived, is(userId)); assertThat(testListener.userWasNull, is(false)); @@ -84,11 +84,11 @@ public void onWebCallUserSeedChange_listenerTriggered() throws Exception { public static class TestUserSeedChangeListener extends UserSeedChangeListener { String lastUserIdReceived; boolean userWasNull; - - @Override + + @Override public void onUserSeedRenewed(@NonNull User user) { if (user == null) { - userWasNull = true; + userWasNull = true; } lastUserIdReceived = user.getId(); } diff --git a/test/src/test/java/jenkins/security/seed/UserSeedPropertyTest.java b/test/src/test/java/jenkins/security/seed/UserSeedPropertyTest.java index 3b4e49106460..03f92171afba 100644 --- a/test/src/test/java/jenkins/security/seed/UserSeedPropertyTest.java +++ b/test/src/test/java/jenkins/security/seed/UserSeedPropertyTest.java @@ -258,7 +258,7 @@ public void userSeedSection_isCorrectlyDisplayed() throws Exception { HtmlPage htmlPage = wc.goTo(alice.getUrl() + "/configure"); htmlPage.getDocumentElement().getOneHtmlElementByAttribute("div", "class", "user-seed-panel"); } - + @Test public void userSeedSection_isCorrectlyHidden_withSpecificSetting() throws Exception { boolean currentStatus = UserSeedProperty.HIDE_USER_SEED_SECTION; @@ -286,7 +286,7 @@ public void userSeedSection_isCorrectlyHidden_withSpecificSetting() throws Excep UserSeedProperty.HIDE_USER_SEED_SECTION = currentStatus; } } - + private void assertUserConnected(JenkinsRule.WebClient wc, String expectedUsername) throws Exception { XmlPage page = (XmlPage) wc.goTo("whoAmI/api/xml", "application/xml"); assertThat(page, hasXPath("//name", is(expectedUsername))); diff --git a/test/src/test/java/jenkins/security/stapler/CustomRoutingDecisionProviderTest.java b/test/src/test/java/jenkins/security/stapler/CustomRoutingDecisionProviderTest.java index e6c3c689b2d7..111437f37dcd 100644 --- a/test/src/test/java/jenkins/security/stapler/CustomRoutingDecisionProviderTest.java +++ b/test/src/test/java/jenkins/security/stapler/CustomRoutingDecisionProviderTest.java @@ -45,10 +45,10 @@ @Issue("SECURITY-400") @For(RoutingDecisionProvider.class) public class CustomRoutingDecisionProviderTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @TestExtension("customRoutingWhitelistProvider") public static class XxxBlacklister extends RoutingDecisionProvider { @Override @@ -59,40 +59,40 @@ public Decision decide(@NonNull String signature) { return Decision.UNKNOWN; } } - + @TestExtension public static class OneMethodIsBlacklisted implements UnprotectedRootAction { @Override public @CheckForNull String getUrlName() { return "custom"; } - + @Override public String getDisplayName() { return null; } - + @Override public String getIconFileName() { return null; } - + public StaplerAbstractTest.Renderable getLegitGetter() { return new StaplerAbstractTest.Renderable(); } - + public StaplerAbstractTest.Renderable getLegitxxxGetter() { return new StaplerAbstractTest.Renderable(); } } - + private static class Renderable { public void doIndex() {replyOk();} - + @WebMethod(name = "valid") public void valid() {replyOk();} } - + private static void replyOk() { StaplerResponse resp = Stapler.getCurrentResponse(); try { @@ -102,12 +102,12 @@ private static void replyOk() { throw new UncheckedIOException(e); } } - + @Test public void customRoutingWhitelistProvider() throws Exception { Page okPage = j.createWebClient().goTo("custom/legitGetter", null); assertThat(okPage.getWebResponse().getStatusCode(), is(200)); - + JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); Page errorPage = wc.goTo("custom/legitxxxGetter", null); diff --git a/test/src/test/java/jenkins/security/stapler/DoActionFilterTest.java b/test/src/test/java/jenkins/security/stapler/DoActionFilterTest.java index 138a5a94db6d..7f1531c60644 100644 --- a/test/src/test/java/jenkins/security/stapler/DoActionFilterTest.java +++ b/test/src/test/java/jenkins/security/stapler/DoActionFilterTest.java @@ -59,17 +59,17 @@ */ @Issue("SECURITY-400") public class DoActionFilterTest extends StaplerAbstractTest { - + @TestExtension public static class TestAccessModifierUrl extends AbstractUnprotectedRootAction { public TestAccessModifier getPublic() {return new TestAccessModifier();} - + protected TestAccessModifier getProtected() {return new TestAccessModifier();} - + TestAccessModifier getInternal() {return new TestAccessModifier();} - + private TestAccessModifier getPrivate() {return new TestAccessModifier();} - + public static class TestAccessModifier { @GET public String doValue() { @@ -77,7 +77,7 @@ public String doValue() { } } } - + @Test public void testProtectedMethodDispatch() throws Exception { try { @@ -92,200 +92,200 @@ public void testProtectedMethodDispatch() throws Exception { x = assertThrows("should not have allowed private access", FailingHttpStatusCodeException.class, () -> wc.goTo("testAccessModifierUrl/private/value", null)); assertEquals(HttpServletResponse.SC_NOT_FOUND, x.getStatusCode()); } - + //================================= doXxx methods ================================= - + @TestExtension public static class TestNewRulesOk extends AbstractUnprotectedRootAction { /* * Method signature */ - + public static void doStaticWithRequest(StaplerRequest request) { replyOk(); } - + public void doWithRequest(StaplerRequest request) { replyOk(); } - + public void doWithHttpRequest(HttpServletRequest request) { replyOk(); } - + // the return type is not taken into consideration if it's not a HttpResponse, it will not prevent the method // to be considered as a web method public String doWithRequestAndReturnString(StaplerRequest request) { return "ok"; } - + public void doWithResponse(StaplerResponse response) { replyOk(); } - + public void doWithHttpResponse(HttpServletResponse response) { replyOk(); } - + public void doWithThrowHttpResponseException() throws HttpResponses.HttpResponseException { replyOk(); } - - // special cases, child of above classes, normally reachable, as it satisfies the contract + + // special cases, child of above classes, normally reachable, as it satisfies the contract // that requires to throw an exception that is an HttpResponseException public void doWithThrowHttpResponseExceptionChild() throws HttpResponseExceptionChild { replyOk(); } - + // the declared exception just has to implement HttpResponse public void doWithThrowExceptionImplementingOnlyHttpResponse() throws ExceptionImplementingOnlyHttpResponse { replyOk(); } - + public void doWithThrowOtherException() throws IOException { replyOk(); } - + public HttpResponse doWithReturnHttpResponse() { return HttpResponses.plainText("ok"); } - + public HttpResponseChild doWithReturnHttpResponseChild() { return new HttpResponseChild(); } - + /* * Method annotations */ - + @WebMethod(name = "webMethodUrl") public void doWebMethod() { replyOk(); } - + // not requiring to have doXxx when using WebMethod @WebMethod(name = "webMethodUrl2") public void webMethod() { replyOk(); } - + @GET public void doAnnotatedGet() { replyOk(); } - + @POST public void doAnnotatedPost() { replyOk(); } - + @PUT public void doAnnotatedPut() { replyOk(); } - + @DELETE public void doAnnotatedDelete() { replyOk(); } - + @RequirePOST public void doAnnotatedRequirePost() { replyOk(); } - + @JavaScriptMethod public void annotatedJavaScriptScriptMethod() { replyOk(); } - + @RespondSuccess public void doAnnotatedResponseSuccess() { replyOk(); } - + @JsonResponse // does not support list public Map doAnnotatedJsonResponse() { return Collections.singletonMap("a", "b"); } - + @LimitedTo("admin") public void doAnnotatedLimitedTo() { replyOk(); } - + /* * Parameter annotation */ - + public void doAnnotatedParamQueryParameter(@QueryParameter String value) { replyOk(); } - + public void doAnnotatedParamAncestorInPath(@AncestorInPath DoActionFilterTest parent) { replyOk(); } - + public void doAnnotatedParamHeader(@Header("test-header") String testHeader) { replyOk(); } - + public void doAnnotatedParamJsonBody(@JsonBody Map names) { replyOk(); } - + public void doAnnotatedParamSubmittedForm(@SubmittedForm JSONObject form) { replyOk(); } - + /* * Parameter annotation */ - + public void do_CallMeBecauseOfMyUnderscore(StaplerRequest request) { replyOk(); } - + public void do$CallMeBecauseOfMyDollar(StaplerRequest request) { replyOk(); } } - + public static class HttpResponseChild implements HttpResponse { @Override public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { replyOk(); } } - + public abstract static class HttpResponseExceptionChild extends HttpResponses.HttpResponseException { } - + public static class ExceptionImplementingOnlyHttpResponse extends RuntimeException implements HttpResponse { - @Override + @Override public void generateResponse(StaplerRequest staplerRequest, StaplerResponse staplerResponse, Object o) throws IOException, ServletException { replyOk(); } } - + //########### actual test methods ########### @Test public void testMethodSignatureOk_staticWithRequest() throws Exception { assertReachable("testNewRulesOk/staticWithRequest/"); } - + @Test public void testMethodSignatureOk_withRequest() throws Exception { assertReachable("testNewRulesOk/withRequest/"); } - + @Test public void testMethodSignatureOk_withRequestAndReturnString() throws Exception { assertReachable("testNewRulesOk/withRequestAndReturnString/"); } - + @Test public void testMethodSignatureOk_withHttpRequest() throws Exception { assertReachable("testNewRulesOk/withHttpRequest/"); } - + @Test public void testMethodSignatureOk_withHttpResponse() throws Exception { assertReachable("testNewRulesOk/withHttpResponse/"); } - + @Test public void testMethodSignatureOk_withResponse() throws Exception { assertReachable("testNewRulesOk/withResponse/"); } - + @Test public void testMethodSignatureOk_withThrowHttpResponseException() throws Exception { assertReachable("testNewRulesOk/withThrowHttpResponseException/"); } - + @Test public void testMethodSignatureOk_withThrowHttpResponseExceptionChild() throws Exception { assertReachable("testNewRulesOk/withThrowHttpResponseExceptionChild/"); } - + @Test public void testMethodSignatureOk_withThrowExceptionImplementingOnlyHttpResponse() throws Exception { assertReachable("testNewRulesOk/withThrowExceptionImplementingOnlyHttpResponse/"); } - + @Test public void testMethodSignatureOk_withThrowOtherException() throws Exception { assertNotReachable("testNewRulesOk/withThrowOtherException/"); } - + @Test public void testMethodSignatureOk_withReturnHttpResponse() throws Exception { assertReachable("testNewRulesOk/withReturnHttpResponse/"); } - + @Test public void testMethodSignatureOk_withReturnHttpResponseChild() throws Exception { assertReachable("testNewRulesOk/withReturnHttpResponseChild/"); } - + @Test public void testAnnotatedMethodOk_webMethodUrl() throws Exception { assertReachable("testNewRulesOk/webMethodUrl/"); } - + @Test public void testAnnotatedMethodOk_webMethodUrl2() throws Exception { assertReachable("testNewRulesOk/webMethodUrl2/"); } - + @Test public void testAnnotatedMethodOk_annotatedGet() throws Exception { assertReachable("testNewRulesOk/annotatedGet/"); } - + @Test public void testAnnotatedMethodOk_annotatedPost() throws Exception { WebRequest settings = new WebRequest(new URL(j.getURL(), "testNewRulesOk/annotatedPost/")); @@ -293,7 +293,7 @@ public void testAnnotatedMethodOk_annotatedPost() throws Exception { settings.setRequestBody(""); assertReachableWithSettings(settings); } - + @Test public void testAnnotatedMethodOk_annotatedPut() throws Exception { WebRequest settings = new WebRequest(new URL(j.getURL(), "testNewRulesOk/annotatedPut/")); @@ -301,12 +301,12 @@ public void testAnnotatedMethodOk_annotatedPut() throws Exception { settings.setRequestBody(""); assertReachableWithSettings(settings); } - + @Test public void testAnnotatedMethodOk_annotatedDelete() throws Exception { assertReachable("testNewRulesOk/annotatedDelete/", HttpMethod.DELETE); } - + @Test public void testAnnotatedMethodOk_annotatedRequirePost() throws Exception { WebRequest settings = new WebRequest(new URL(j.getURL(), "testNewRulesOk/annotatedRequirePost/")); @@ -314,7 +314,7 @@ public void testAnnotatedMethodOk_annotatedRequirePost() throws Exception { settings.setRequestBody(""); assertReachableWithSettings(settings); } - + @Test public void testAnnotatedMethodOk_annotatedJavaScriptScriptMethod() throws Exception { webApp.setCrumbIssuer(new CrumbIssuer() { @@ -322,26 +322,26 @@ public void testAnnotatedMethodOk_annotatedJavaScriptScriptMethod() throws Excep public String issueCrumb(StaplerRequest request) { return "test"; } - + @Override public void validateCrumb(StaplerRequest request, String submittedCrumb) { // no exception thrown = validated } }); - - + + WebRequest settings = new WebRequest(new URL(j.getURL(), "testNewRulesOk/annotatedJavaScriptScriptMethod/")); settings.setAdditionalHeader("Content-Type", "application/x-stapler-method-invocation"); settings.setHttpMethod(HttpMethod.POST); settings.setRequestBody(JSONArray.fromObject(Collections.emptyList()).toString()); assertReachableWithSettings(settings); } - + @Test public void testAnnotatedMethodOk_annotatedResponseSuccess() throws Exception { assertReachable("testNewRulesOk/annotatedResponseSuccess/"); } - + @Test public void testAnnotatedMethodOk_annotatedJsonResponse() throws Exception { WebRequest settings = new WebRequest(new URL(j.getURL(), "testNewRulesOk/annotatedJsonResponse/")); @@ -350,33 +350,33 @@ public void testAnnotatedMethodOk_annotatedJsonResponse() throws Exception { Page page = wc.getPage(settings); assertEquals(200, page.getWebResponse().getStatusCode()); } - + @Test public void testAnnotatedMethodOk_annotatedLimitedTo() throws Exception { FailingHttpStatusCodeException e = assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(new URL(j.getURL(), "testNewRulesOk/annotatedLimitedTo/"))); assertEquals(500, e.getStatusCode()); assertTrue(e.getResponse().getContentAsString().contains("Needs to be in role")); } - + @Test public void testAnnotatedParameterOk_annotatedParamQueryParameter() throws Exception { // parameter is optional by default assertReachable("testNewRulesOk/annotatedParamQueryParameter/"); assertReachable("testNewRulesOk/annotatedParamQueryParameter/?value=test"); } - + @Test public void testAnnotatedParameterOk_annotatedParamAncestorInPath() throws Exception { assertReachable("testNewRulesOk/annotatedParamAncestorInPath/"); } - + @Test public void testAnnotatedParameterOk_annotatedParamHeader() throws Exception { WebRequest settings = new WebRequest(new URL(j.getURL(), "testNewRulesOk/annotatedParamHeader/")); settings.setAdditionalHeader("test-header", "TestBrowser"); assertReachableWithSettings(settings); } - + @Test public void testAnnotatedParameterOk_annotatedParamJsonBody() throws Exception { WebRequest settings = new WebRequest(new URL(j.getURL(), "testNewRulesOk/annotatedParamJsonBody/")); @@ -386,12 +386,12 @@ public void testAnnotatedParameterOk_annotatedParamJsonBody() throws Exception { settings.setRequestBody(JSONObject.fromObject(Collections.singletonMap("name", "Test")).toString()); assertReachableWithSettings(settings); } - + @Test public void testAnnotatedParameterOk_annotatedParamSubmittedForm() throws Exception { WebRequest settings = new WebRequest(new URL(j.getURL(), "testNewRulesOk/annotatedParamSubmittedForm/")); settings.setHttpMethod(HttpMethod.POST); - + settings.setRequestParameters(Collections.singletonList( new NameValuePair( "json", @@ -400,199 +400,199 @@ public void testAnnotatedParameterOk_annotatedParamSubmittedForm() throws Except )); assertReachableWithSettings(settings); } - + @Test public void testOk__CallMeBecauseOfMyUnderscore() throws Exception { assertReachable("testNewRulesOk/_CallMeBecauseOfMyUnderscore/"); } - + @Test public void testOk_$CallMeBecauseOfMyDollar() throws Exception { assertReachable("testNewRulesOk/$CallMeBecauseOfMyDollar/"); } - + @TestExtension public static class TestNewRulesOkDynamic extends AbstractUnprotectedRootAction { // sufficiently magical name to be reached public void doDynamic() { replyOk(); } } - - + + @TestExtension public static class TestNewRulesOkIndex extends AbstractUnprotectedRootAction { // considered as index @WebMethod(name = "") public void methodWithoutNameEqualIndex() { replyOk(); } } - + @TestExtension public static class TestNewRulesOkDoIndex extends AbstractUnprotectedRootAction { public void doIndex() { replyOk(); } } - + @Test public void testSpecialCasesOk() throws Exception { assertReachable("testNewRulesOkDynamic/anyString/"); assertReachable("testNewRulesOkIndex/"); assertReachable("testNewRulesOkDoIndex/"); } - + // those methods are accepted in legacy system but potentially dangerous @TestExtension public static class TestNewRulesNotOk extends AbstractUnprotectedRootAction { // do not respect the do[^a-z].* format public void dontCallMeBecauseOfMyDont(StaplerRequest request) { replyOk(); } - - // do not seem to be an expected web method, in case a developer has such methods, + + // do not seem to be an expected web method, in case a developer has such methods, // addition of WebMethod annotation is sufficient public void doSomething() { replyOk(); } - + // returning a String is not sufficient to be considered as a web method public String doReturnString() { return "ok"; } - + // returning a super class of HttpResponse is not sufficient public Object doReturnObject() { return "ok"; } } - + @Test public void testNotOk_ntCallMeBecauseOfMyDont() throws Exception { assertNotReachable("testNewRulesNotOk/ntCallMeBecauseOfMyDont/"); assertDoActionRequestWasBlockedAndResetFlag(); } - + @Test public void testNotOk_something() throws Exception { assertNotReachable("testNewRulesNotOk/something/"); assertDoActionRequestWasBlockedAndResetFlag(); } - + @Test public void testNotOk_returnString() throws Exception { assertNotReachable("testNewRulesNotOk/returnString/"); assertDoActionRequestWasBlockedAndResetFlag(); } - + @Test public void testNotOk_returnObject() throws Exception { assertNotReachable("testNewRulesNotOk/returnObject/"); assertDoActionRequestWasBlockedAndResetFlag(); } - + @TestExtension public static class TestNewRulesNotOkSpecialCases extends AbstractUnprotectedRootAction { public void doWithServletRequest(ServletRequest request) { replyOk(); } - + public void doWithServletResponse(ServletResponse response) { replyOk(); } - + // special cases, child of above classes public void doWithRequestImpl(RequestImpl request) { replyOk(); } - + public void doWithResponseImpl(ResponseImpl response) { replyOk(); } - + public void doWithRequestAndResponse(RequestAndResponse requestAndResponse) { replyOk(); } - + // special case to keep Groovy parameter name, but does not seem to indicate it's automatically a web method @CapturedParameterNames("req") public void doAnnotatedResponseSuccess(Object req) { replyOk(); } - + // // as mentioned in its documentation, it requires to have JavaScriptMethod, that has its own test // @JsonOutputFilter // public void doAnnotatedJsonOutputFilter() { replyOk(); } } - + public abstract static class RequestAndResponse implements StaplerRequest, StaplerResponse { @Override public CollectionAndEnumeration getHeaderNames() { return null; } - + @Override public CollectionAndEnumeration getHeaders(String name) { return null; } - + public abstract static class CollectionAndEnumeration implements Collection, Enumeration { } } - + @Test public void testNotOkSpecialCases_withServletRequest() throws Exception { assertNotReachable("testNewRulesNotOkSpecialCases/withServletRequest/"); assertDoActionRequestWasBlockedAndResetFlag(); } - + @Test public void testNotOkSpecialCases_withServletResponse() throws Exception { assertNotReachable("testNewRulesNotOkSpecialCases/withServletResponse/"); assertDoActionRequestWasBlockedAndResetFlag(); } - + @Test public void testNotOkSpecialCases_withRequestImpl() throws Exception { assertNotReachable("testNewRulesNotOkSpecialCases/withRequestImpl/"); assertDoActionRequestWasBlockedAndResetFlag(); } - + @Test public void testNotOkSpecialCases_withResponseImpl() throws Exception { assertNotReachable("testNewRulesNotOkSpecialCases/withResponseImpl/"); assertDoActionRequestWasBlockedAndResetFlag(); } - + @Test public void testNotOkSpecialCases_withRequestAndResponse() throws Exception { assertNotReachable("testNewRulesNotOkSpecialCases/withRequestAndResponse/"); assertDoActionRequestWasBlockedAndResetFlag(); } - + @Test public void testNotOkSpecialCases_annotatedResponseSuccess() throws Exception { assertNotReachable("testNewRulesNotOkSpecialCases/annotatedResponseSuccess/"); assertDoActionRequestWasBlockedAndResetFlag(); } - + // now JsonOutputFilter is accepted as a web method annotation -// @Test +// @Test // public void testNotOkSpecialCases_annotatedJsonOutputFilter() throws Exception { // assertNotReachable("testNewRulesNotOkSpecialCases/annotatedJsonOutputFilter/"); // assertDoActionRequestWasBlockedAndResetFlag(); // } - + //================================= class inheritance ================================= - + public static class A { public void doNotAnnotatedAtAll() { replyOk(); } - + @WebMethod(name = "onlyAnnotatedInA") public void doOnlyAnnotatedInA() { replyOk(); } - + public void doOnlyAnnotatedInB() { replyOk(); } - + @WebMethod(name = "onlyAnnotatedInA-notOverrided") public void doOnlyAnnotatedInANotOverrided() { replyOk(); } - + @WebMethod(name = "annotatedButDifferent1") public void doAnnotatedButDifferent() { replyOk(); } } - + public static class B extends A { @Override public void doNotAnnotatedAtAll() { replyOk(); } - + @Override public void doOnlyAnnotatedInA() { replyOk(); } - + @Override @WebMethod(name = "onlyAnnotatedInB") public void doOnlyAnnotatedInB() { replyOk(); } - + // doOnlyAnnotatedInANotOverrided: not overrided - + @Override @WebMethod(name = "annotatedButDifferent2") public void doAnnotatedButDifferent() { replyOk(); } } - + @TestExtension public static class ABCase extends AbstractUnprotectedRootAction implements StaplerProxy { @Override @@ -600,28 +600,28 @@ public B getTarget() { return new B(); } } - + @Test public void testClassInheritance_notAnnotatedAtAll() throws Exception { assertNotReachable("aBCase/notAnnotatedAtAll/"); assertDoActionRequestWasBlockedAndResetFlag(); } - + @Test public void testClassInheritance_onlyAnnotatedInA() throws Exception { assertReachable("aBCase/onlyAnnotatedInA/"); } - + @Test public void testClassInheritance_onlyAnnotatedInB() throws Exception { assertReachable("aBCase/onlyAnnotatedInB/"); } - + @Test public void testClassInheritance_onlyAnnotatedInANotOverrided() throws Exception { assertNotReachable("aBCase/onlyAnnotatedInANotOverrided/"); } - + @Test public void testClassInheritance_annotatedButDifferent1() throws Exception { // only the last webMethod annotation is used @@ -629,48 +629,48 @@ public void testClassInheritance_annotatedButDifferent1() throws Exception { // assertReachable("b/annotatedButDifferent1/"); assertNotReachable("aBCase/annotatedButDifferent1/"); } - + @Test public void testClassInheritance_annotatedButDifferent2() throws Exception { assertReachable("aBCase/annotatedButDifferent2/"); } - + //================================= interface implementation ================================= public interface I { void doNotAnnotated(); - + @WebMethod(name = "annotatedBoth") void doAnnotatedBoth(); - + @WebMethod(name = "annotatedOnlyI") void doAnnotatedOnlyI(); - + void doAnnotatedOnlyJ(); - + @WebMethod(name = "annotatedButDifferent1") void doAnnotatedButDifferent(); } - + public static class J implements I { @Override public void doNotAnnotated() { replyOk(); } - + @Override @WebMethod(name = "annotatedBoth") public void doAnnotatedBoth() { replyOk(); } - + @Override public void doAnnotatedOnlyI() { replyOk(); } - + @Override @WebMethod(name = "annotatedOnlyJ") public void doAnnotatedOnlyJ() { replyOk(); } - + @Override @WebMethod(name = "annotatedButDifferent2") public void doAnnotatedButDifferent() { replyOk(); } } - + @TestExtension public static class IJCase extends AbstractUnprotectedRootAction implements StaplerProxy { @Override @@ -678,28 +678,28 @@ public J getTarget() { return new J(); } } - + @Test public void testInterfaceImplementation_notAnnotated() throws Exception { assertNotReachable("iJCase/notAnnotated/"); assertDoActionRequestWasBlockedAndResetFlag(); } - + @Test public void testInterfaceImplementation_annotatedBoth() throws Exception { assertReachable("iJCase/annotatedBoth/"); } - + @Test public void testInterfaceImplementation_annotatedOnlyI() throws Exception { assertReachable("iJCase/annotatedOnlyI/"); } - + @Test public void testInterfaceImplementation_annotatedOnlyJ() throws Exception { assertReachable("iJCase/annotatedOnlyJ/"); } - + @Test public void testInterfaceImplementation_annotatedButDifferent1() throws Exception { // only the last webMethod annotation is used @@ -707,7 +707,7 @@ public void testInterfaceImplementation_annotatedButDifferent1() throws Exceptio // assertReachable("j/annotatedButDifferent1/"); assertNotReachable("iJCase/annotatedButDifferent1/"); } - + @Test public void testInterfaceImplementation_annotatedButDifferent2() throws Exception { assertReachable("iJCase/annotatedButDifferent2/"); diff --git a/test/src/test/java/jenkins/security/stapler/GetterMethodFilterTest.java b/test/src/test/java/jenkins/security/stapler/GetterMethodFilterTest.java index c4fe7190d89a..a9f4991e626a 100644 --- a/test/src/test/java/jenkins/security/stapler/GetterMethodFilterTest.java +++ b/test/src/test/java/jenkins/security/stapler/GetterMethodFilterTest.java @@ -52,16 +52,16 @@ @Issue("SECURITY-400") @For(TypedFilter.class) public class GetterMethodFilterTest extends StaplerAbstractTest { - + @TestExtension public static class TestWithReturnJavaPlatformObject extends AbstractUnprotectedRootAction { public static boolean called = false; - + public String getString() { return "a";} - + // cannot provide side-effect since the String has no side-effect methods public Object getObjectString() { return "a";} - + // but it opens wide range of potentially dangerous classes public Object getObjectCustom() { return new Object() { @@ -71,9 +71,9 @@ public void doIndex() { } }; } - + public Point getPoint() { return new Point(1, 2);} - + public Point getPointCustomChild() { return new Point() { // in order to provide a web entry-point @@ -82,7 +82,7 @@ public void doIndex() { } }; } - + public Point getPointWithListener() { return new Point() { @Override @@ -94,33 +94,33 @@ public double getX() { }; } } - + @Test public void testWithReturnJavaPlatformObject_string() throws Exception { assertNotReachable("testWithReturnJavaPlatformObject/string/"); } - + @Test public void testWithReturnJavaPlatformObject_objectString() throws Exception { assertNotReachable("testWithReturnJavaPlatformObject/objectString/"); } - + @Test public void testWithReturnJavaPlatformObject_objectCustom() throws Exception { assertNotReachable("testWithReturnJavaPlatformObject/objectCustom/"); } - + @Test public void testWithReturnJavaPlatformObject_point() throws Exception { assertNotReachable("testWithReturnJavaPlatformObject/point/"); } - + // previously reachable and so potentially open to future security vulnerability @Test public void testWithReturnJavaPlatformObject_pointCustomChild() throws Exception { assertNotReachable("testWithReturnJavaPlatformObject/pointCustomChild/"); } - + @Test public void testWithReturnJavaPlatformObject_pointWithListener() throws Exception { TestWithReturnJavaPlatformObject.called = false; @@ -129,13 +129,13 @@ public void testWithReturnJavaPlatformObject_pointWithListener() throws Exceptio assertNotReachable("testWithReturnJavaPlatformObject/pointWithListener/x/"); assertFalse(TestWithReturnJavaPlatformObject.called); } - + @TestExtension public static class TestWithReturnMultiple extends AbstractUnprotectedRootAction { public List getList() { return Arrays.asList(new Renderable(), new Renderable()); } - + // as we cannot determine the element class due to type erasure, this is reachable public List getListOfPoint() { return Collections.singletonList(new RenderablePoint()); @@ -146,14 +146,14 @@ public List> getListOfList() { } public Renderable[] getArray() { return new Renderable[]{new Renderable(), new Renderable()};} - - // will not be accepted since the componentType is from JVM + + // will not be accepted since the componentType is from JVM public Point[] getArrayOfPoint() { return new Point[]{new Point() { public void doIndex() {replyOk();} }}; } - + public Renderable[][] getArrayOfArray() { return new Renderable[][] { new Renderable[] { @@ -162,24 +162,24 @@ public Renderable[][] getArrayOfArray() { }, }; } - + @SuppressWarnings("unchecked") public List[] getArrayOfList() { List list = Arrays.asList(new Renderable(), new Renderable()); return (List[]) Collections.singletonList(list).toArray(new List[0]); } - + public List getListOfArray() { return Collections.singletonList( new Renderable[]{new Renderable(), new Renderable()} ); } - + public Map getMap() { return Collections.singletonMap("a", new Renderable()); } } - + @Test public void testWithReturnMultiple_list() throws Exception { assertNotReachable("testWithReturnMultiple/list/"); @@ -187,14 +187,14 @@ public void testWithReturnMultiple_list() throws Exception { assertNotReachable("testWithReturnMultiple/list/1/"); assertNotReachable("testWithReturnMultiple/list/2/"); } - + @Test public void testWithReturnMultiple_listOfPoint() throws Exception { assertNotReachable("testWithReturnMultiple/listOfPoint/"); assertNotReachable("testWithReturnMultiple/listOfPoint/0/"); assertNotReachable("testWithReturnMultiple/listOfPoint/1/"); } - + @Test public void testWithReturnMultiple_listOfList() throws Exception { assertNotReachable("testWithReturnMultiple/listOfList/"); @@ -204,7 +204,7 @@ public void testWithReturnMultiple_listOfList() throws Exception { assertNotReachable("testWithReturnMultiple/listOfList/0/1/"); assertNotReachable("testWithReturnMultiple/listOfList/0/2/"); } - + @Test public void testWithReturnMultiple_array() throws Exception { assertNotReachable("testWithReturnMultiple/array/"); @@ -212,14 +212,14 @@ public void testWithReturnMultiple_array() throws Exception { assertReachable("testWithReturnMultiple/array/1/"); assertNotReachable("testWithReturnMultiple/array/2/"); } - + @Test public void testWithReturnMultiple_arrayOfPoint() throws Exception { assertNotReachable("testWithReturnMultiple/arrayOfPoint/"); assertNotReachable("testWithReturnMultiple/arrayOfPoint/0/"); assertNotReachable("testWithReturnMultiple/arrayOfPoint/1/"); } - + @Test public void testWithReturnMultiple_arrayOfArray() throws Exception { assertNotReachable("testWithReturnMultiple/arrayOfArray/"); @@ -229,7 +229,7 @@ public void testWithReturnMultiple_arrayOfArray() throws Exception { assertReachable("testWithReturnMultiple/arrayOfArray/0/1/"); assertNotReachable("testWithReturnMultiple/arrayOfArray/0/2/"); } - + @Test public void testWithReturnMultiple_arrayOfList() throws Exception { assertNotReachable("testWithReturnMultiple/arrayOfList/"); @@ -239,7 +239,7 @@ public void testWithReturnMultiple_arrayOfList() throws Exception { assertNotReachable("testWithReturnMultiple/arrayOfList/0/1/"); assertNotReachable("testWithReturnMultiple/arrayOfList/0/2/"); } - + @Test public void testWithReturnMultiple_listOfArray() throws Exception { assertNotReachable("testWithReturnMultiple/listOfArray/"); @@ -249,14 +249,14 @@ public void testWithReturnMultiple_listOfArray() throws Exception { assertNotReachable("testWithReturnMultiple/listOfArray/0/1/"); assertNotReachable("testWithReturnMultiple/listOfArray/0/2/"); } - + @Test public void testWithReturnMultiple_map() throws Exception { assertNotReachable("testWithReturnMultiple/map/"); assertNotReachable("testWithReturnMultiple/map/a/"); assertNotReachable("testWithReturnMultiple/map/b/"); } - + @TestExtension public static class TestWithReturnCoreObject extends AbstractUnprotectedRootAction { public View.People getPeople() { @@ -264,7 +264,7 @@ public View.People getPeople() { return new View.People(Jenkins.get()); } } - + @Test public void testWithReturnCoreObject_people() throws Exception { assertReachableWithoutOk("testWithReturnCoreObject/people/"); @@ -275,31 +275,31 @@ public void testTopLevelItemIsLegal() throws Exception { TopLevelItem item = j.createFreeStyleProject(); assertReachableWithoutOk("job/" + item.getName()); } - + @TestExtension public static class TestWithReturnPluginObject extends AbstractUnprotectedRootAction { public Folder getFolder() { return new Folder(Jenkins.get(), "testFolder"); } } - + @Test public void testWithReturnPluginObject_folder() throws Exception { // the search part is just to get something from the call assertReachableWithoutOk("testWithReturnPluginObject/folder/search/suggest/?query=xxx"); } - + // full package name just to be explicit @TestExtension public static class TestWithReturnThirdPartyObject extends AbstractUnprotectedRootAction { public Base64 getBase64() { return new Base64(); } - + public Encoder getEncoder() { return new Base64(); } - + public Encoder getEncoderCustomChild() { return new Encoder() { @Override @@ -307,7 +307,7 @@ public Object encode(Object source) throws EncoderException { // it's not about implementation... return null; } - + public void doIndex() { // it's about sending a message replyOk(); @@ -315,185 +315,185 @@ public void doIndex() { }; } } - + // the class itself was reachable but no more interaction are available and so return 404 - + @Test public void testWithReturnThirdPartyObject_base32() throws Exception { assertNotReachable("testWithReturnThirdPartyObject/base32/"); } - + // the class itself was reachable but no more interaction are available and so return 404, // in case there is some callable methods, we could create some side-effect even we got 404 @Test public void testWithReturnThirdPartyObject_encoder() throws Exception { assertNotReachable("testWithReturnThirdPartyObject/encoder/"); } - + // as we add a entry-point in the class, now it can propose some interaction, - // dangerous behavior that is not prohibited + // dangerous behavior that is not prohibited @Test public void testWithReturnThirdPartyObject_encoderCustomChild() throws Exception { assertNotReachable("testWithReturnThirdPartyObject/encoderCustomChild/"); } - - + + //================================= getter methods with primitives ================================= - + @TestExtension public static class TestWithReturnPrimitives extends AbstractUnprotectedRootAction { public int getInteger() { return 1;} - + public Integer getIntegerObject() { return 1;} - + public long getLong() { return 1L;} - + public Long getLongObject() { return 1L;} - + public short getShort() { return (short) 1;} - + public Short getShortObject() { return 1;} - + public byte getByte() { return (byte) 1;} - + public Byte getByteObject() { return (byte) 1;} - + public boolean getBoolean() { return true;} - + public Boolean getBooleanObject() { return Boolean.TRUE;} - + public char getChar() { return 'a';} - + public Character getCharObject() { return 'a';} - + public float getFloat() { return 1.0f;} - + public Float getFloatObject() { return 1.0f;} - + public double getDouble() { return 1.0;} - + public Double getDoubleObject() { return 1.0;} - + public void getVoid() { } - + public Void getVoidObject() { return null; } } - + @Test public void testTestWithReturnPrimitives_integer() throws Exception { assertNotReachable("testWithReturnPrimitives/integer/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_integerObject() throws Exception { assertNotReachable("testWithReturnPrimitives/integerObject/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_long() throws Exception { assertNotReachable("testWithReturnPrimitives/long/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_longObject() throws Exception { assertNotReachable("testWithReturnPrimitives/longObject/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_short() throws Exception { assertNotReachable("testWithReturnPrimitives/short/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_shortObject() throws Exception { assertNotReachable("testWithReturnPrimitives/shortObject/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_byte() throws Exception { assertNotReachable("testWithReturnPrimitives/byte/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_byteObject() throws Exception { assertNotReachable("testWithReturnPrimitives/byteObject/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_boolean() throws Exception { assertNotReachable("testWithReturnPrimitives/boolean/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_booleanObject() throws Exception { assertNotReachable("testWithReturnPrimitives/booleanObject/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_char() throws Exception { assertNotReachable("testWithReturnPrimitives/char/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_charObject() throws Exception { assertNotReachable("testWithReturnPrimitives/charObject/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_float() throws Exception { assertNotReachable("testWithReturnPrimitives/float/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_floatObject() throws Exception { assertNotReachable("testWithReturnPrimitives/floatObject/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_double() throws Exception { assertNotReachable("testWithReturnPrimitives/double/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_doubleObject() throws Exception { assertNotReachable("testWithReturnPrimitives/doubleObject/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_void() throws Exception { assertNotReachable("testWithReturnPrimitives/void/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void testTestWithReturnPrimitives_voidObject() throws Exception { assertNotReachable("testWithReturnPrimitives/voidObject/"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + //================================= getter methods ================================= - + @TestExtension public static class TestWithReturnWithinStaplerScope extends DoActionFilterTest.AbstractUnprotectedRootAction { public Renderable getRenderable() { return new Renderable();} } - + @Test public void testWithReturnWithinStaplerScope_renderable() throws Exception { assertReachable("testWithReturnWithinStaplerScope/renderable/"); diff --git a/test/src/test/java/jenkins/security/stapler/Security400Test.java b/test/src/test/java/jenkins/security/stapler/Security400Test.java index 6ed8dfdc3f5c..8a937cea4b8e 100644 --- a/test/src/test/java/jenkins/security/stapler/Security400Test.java +++ b/test/src/test/java/jenkins/security/stapler/Security400Test.java @@ -77,9 +77,9 @@ public class Security400Test { @Rule public JenkinsRule j = new JenkinsRule(); - + private static boolean filteredDoActionTriggered = false; - + @Before public void prepareFilterListener(){ WebApp webApp = WebApp.get(j.jenkins.servletContext); @@ -92,21 +92,21 @@ public void prepareFilterListener(){ return false; }); } - + @After public void resetFilter(){ filteredDoActionTriggered = false; } - + private void assertRequestWasBlockedAndResetFlag(){ assertTrue("No request was blocked", filteredDoActionTriggered); filteredDoActionTriggered = false; } - + private void assertRequestWasNotBlocked(){ assertFalse("There was at least a request that was blocked", filteredDoActionTriggered); } - + @Test @Issue("SECURITY-391") public void asyncDoRun() throws Exception { @@ -114,26 +114,26 @@ public void asyncDoRun() throws Exception { Thread.sleep(1000); // give the thread a moment to finish assertFalse("should never have run", ran); } - + private static boolean ran; - + @TestExtension("asyncDoRun") public static class Work extends AsyncPeriodicWork { public Work() { super("Test"); } - + @Override public long getRecurrencePeriod() { return Long.MAX_VALUE; // do not run after init() } - + @Override protected void execute(TaskListener listener) throws IOException, InterruptedException { ran = true; } } - + // require a dependency on cloudbees-folder-plugin @Test @Issue("SECURITY-397") @@ -142,7 +142,7 @@ public void folderCronDoRun() throws Exception { j.createWebClient().assertFails("extensionList/" + PeriodicWork.class.getName() + "/" + FolderCron.class.getName() + "/run", HttpURLConnection.HTTP_NOT_FOUND); assertRequestWasBlockedAndResetFlag(); } - + /** * replacement of "computers/0/executors/0/contextClassLoader/context/handlers/0/sessionManager/stop" attack */ @@ -150,37 +150,37 @@ public void folderCronDoRun() throws Exception { @Issue("SECURITY-404") public void avoidDangerousAccessToSession() throws Exception { j.jenkins.setCrumbIssuer(null); - + j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy( new MockAuthorizationStrategy() .grant(Jenkins.ADMINISTER).everywhere().to("admin") .grant(Jenkins.READ).everywhere().to("user") ); - + JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); wc.login("admin"); - + JenkinsRule.WebClient wc2 = j.createWebClient(); wc2.getOptions().setThrowExceptionOnFailingStatusCode(false); wc2.login("user"); - + Page page; - + page = wc.goTo("whoAmI/api/xml/", null); System.out.println(page.getWebResponse().getContentAsString()); assertThat(page.getWebResponse().getContentAsString(), containsString("false")); - + page = wc2.goTo("whoAmI/api/xml/", null); System.out.println(page.getWebResponse().getContentAsString()); assertThat(page.getWebResponse().getContentAsString(), containsString("false")); - + assertRequestWasNotBlocked(); - + // the doXxx fix prevents the doStop to be executed // and in addition the getXxx fix prevents the getContextHandler to be used as navigation - + // the first beans/0 return the HashedSession // the second beans/0 return the HashSessionManager page = wc2.goTo("adjuncts//webApp/context/contextHandler/beans/0/beans/0/stop", null); @@ -192,71 +192,71 @@ public void avoidDangerousAccessToSession() throws Exception { // assertRequestWasBlockedAndResetFlag(); // getWebApp is now forbidden assertEquals(403, page.getWebResponse().getStatusCode()); - + // if the call was successful, both are disconnected and anonymous would have been true - + page = wc.goTo("whoAmI/api/xml/", null); System.out.println(page.getWebResponse().getContentAsString()); assertThat(page.getWebResponse().getContentAsString(), containsString("false")); - + page = wc2.goTo("whoAmI/api/xml/", null); System.out.println(page.getWebResponse().getContentAsString()); assertThat(page.getWebResponse().getContentAsString(), containsString("false")); - + assertRequestWasNotBlocked(); - + // similar approach but different impact: // can put null into desired session key (no impact yet) // session impl. is HashedSession // page = wc.goTo("adjuncts//webApp/someStapler/currentRequest/session/putOrRemove/ACEGI_SECURITY_CONTEXT/", null); } - + @Test @Issue("SECURITY-404") public void ensureDoStopStillReachable() throws Exception { j.jenkins.setCrumbIssuer(null); JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + // used as a reference passed to the build step AtomicInteger atomicResult = new AtomicInteger(0); FreeStyleProject p = j.createFreeStyleProject(); - + final Semaphore semaphore = new Semaphore(0); - + p.getBuildersList().add(new SemaphoredBuilder(semaphore, atomicResult)); - + // to be sure to reach the correct one j.jenkins.setNumExecutors(1); - + { // preliminary test, calling the stop method without any executor results in 404 WebRequest request = new WebRequest(new URL(j.getURL() + "computers/0/executors/0/stop"), HttpMethod.POST); Page page = wc.getPage(request); assertEquals(404, page.getWebResponse().getStatusCode()); assertRequestWasNotBlocked(); } - + { // first try, we let the build finishes normally QueueTaskFuture futureBuild = p.scheduleBuild2(0); futureBuild.waitForStart(); - + // let the build finishes semaphore.release(1); j.assertBuildStatus(Result.SUCCESS, futureBuild); assertEquals(1, atomicResult.get()); } - + { // second try, we need to reach the stop method in executor to interrupt the build atomicResult.set(0); assertEquals(0, atomicResult.get()); QueueTaskFuture futureBuild = p.scheduleBuild2(0); futureBuild.waitForStart(); - + WebRequest request = new WebRequest(new URL(j.getURL() + "computers/0/executors/0/stop"), HttpMethod.POST); Page page = wc.getPage(request); assertEquals(404, page.getWebResponse().getStatusCode()); assertRequestWasNotBlocked(); - + j.assertBuildStatus(Result.FAILURE, futureBuild); assertEquals(3, atomicResult.get()); } @@ -376,58 +376,58 @@ public void anonCannotReadTextConsole() throws Exception { FullControlOnceLoggedInAuthorizationStrategy authorizationStrategy = new FullControlOnceLoggedInAuthorizationStrategy(); authorizationStrategy.setAllowAnonymousRead(false); j.jenkins.setAuthorizationStrategy(authorizationStrategy); - + JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + FreeStyleProject p = j.createFreeStyleProject(); - + Semaphore semaphore = new Semaphore(0); - + p.getBuildersList().add(new SemaphoredBuilder(semaphore, new AtomicInteger(0))); - + // to be sure to reach the correct one j.jenkins.setNumExecutors(1); - + { // preliminary test, calling the consoleText method without any executor results in 404 Page page = wc.goTo("computers/0/executors/0/currentExecutable/consoleText", null); checkPageIsRedirectedToLogin(page); assertRequestWasNotBlocked(); } - + { // as Connected User, we start the build and try to get the console, ensure current expected behavior still works wc.login("foo"); - + QueueTaskFuture futureBuild = p.scheduleBuild2(0); futureBuild.waitForStart(); - + Page page = wc.goTo("computers/0/executors/0/currentExecutable/consoleText", null); assertEquals(200, page.getWebResponse().getStatusCode()); assertThat(page.getWebResponse().getContentAsString(), containsString(SemaphoredBuilder.START_MESSAGE)); assertRequestWasNotBlocked(); - + semaphore.release(1); j.assertBuildStatus(Result.SUCCESS, futureBuild); } - + { // as Anonymous, we start the build and try to get the console wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + QueueTaskFuture futureBuild = p.scheduleBuild2(0); futureBuild.waitForStart(); - + Page page = wc.goTo("computers/0/executors/0/currentExecutable/consoleText", null); checkPageIsRedirectedToLogin(page); assertThat(page.getWebResponse().getContentAsString(), not(containsString(SemaphoredBuilder.START_MESSAGE))); assertRequestWasNotBlocked(); - + semaphore.release(1); j.assertBuildStatus(Result.SUCCESS, futureBuild); } } - - + + @Test @Issue("SECURITY-404") public void anonCannotAccessExecutorApi() throws Exception { @@ -435,64 +435,64 @@ public void anonCannotAccessExecutorApi() throws Exception { FullControlOnceLoggedInAuthorizationStrategy authorizationStrategy = new FullControlOnceLoggedInAuthorizationStrategy(); authorizationStrategy.setAllowAnonymousRead(false); j.jenkins.setAuthorizationStrategy(authorizationStrategy); - + JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + FreeStyleProject p = j.createFreeStyleProject(); - + Semaphore semaphore = new Semaphore(0); - + p.getBuildersList().add(new SemaphoredBuilder(semaphore, new AtomicInteger(0))); - + // to be sure to reach the correct one j.jenkins.setNumExecutors(1); - + { Page page = wc.goTo("computers/0/executors/0/api/xml", null); checkPageIsRedirectedToLogin(page); assertRequestWasNotBlocked(); } - + { // as Connected User, we start the build and can access the executor api QueueTaskFuture futureBuild = p.scheduleBuild2(0); futureBuild.waitForStart(); - + wc.login("foo"); Page page = wc.goTo("computers/0/executors/0/api/xml", null); assertEquals(200, page.getWebResponse().getStatusCode()); assertThat(page.getWebResponse().getContentAsString(), containsString(p.getUrl())); assertRequestWasNotBlocked(); - + semaphore.release(1); j.assertBuildStatus(Result.SUCCESS, futureBuild); - + wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); } - + { // as Anonymous, we start the build and cannot access the executor api QueueTaskFuture futureBuild = p.scheduleBuild2(0); futureBuild.waitForStart(); - + Page page = wc.goTo("computers/0/executors/0/api/xml", null); checkPageIsRedirectedToLogin(page); assertThat(page.getWebResponse().getContentAsString(), not(containsString(p.getUrl()))); assertRequestWasNotBlocked(); - + semaphore.release(1); j.assertBuildStatus(Result.SUCCESS, futureBuild); } } - + @Test @Issue("SECURITY-404") public void anonCannotAccessJenkinsItemMap() throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + FreeStyleProject p = j.createFreeStyleProject(); - + { // try to access /itemMap/ wc.login("foo"); Page page = wc.goTo("itemMap/" + p.getName() + "/api/xml", null); @@ -501,17 +501,17 @@ public void anonCannotAccessJenkinsItemMap() throws Exception { assertRequestWasBlockedAndResetFlag(); } } - + public static class SemaphoredBuilder extends Builder { private static final String START_MESSAGE = "job started, will try to acquire one permit"; private transient Semaphore semaphore; private transient AtomicInteger atomicInteger; - + SemaphoredBuilder(Semaphore semaphore, AtomicInteger atomicInteger) { this.semaphore = semaphore; this.atomicInteger = atomicInteger; } - + @Override public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { try { @@ -530,138 +530,138 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListen return false; } } - + @TestExtension public static class DescriptorImpl extends Descriptor {} } - + // currently there is no other way to reach logRecorderManager in core / or plugin @Test @Issue("SECURITY-471") public void ensureLogRecordManagerAccessibleOnlyByAdmin() throws Exception { j.jenkins.setCrumbIssuer(null); - + j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy( new MockAuthorizationStrategy() .grant(Jenkins.ADMINISTER).everywhere().to("admin") .grant(Jenkins.READ).everywhere().to("user") ); - + String logNameForAdmin = "testLoggerAdmin"; String logNameForUser = "testLoggerUser"; - + { // admin can do everything JenkinsRule.WebClient wc = j.createWebClient(); wc.login("admin"); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + // ensure the logger does not exist before the creation assertEquals(404, wc.goTo("log/" + logNameForAdmin + "/autoCompleteLoggerName/?value=a", null).getWebResponse().getStatusCode()); assertRequestWasNotBlocked(); - + WebRequest request = new WebRequest(new URL(j.getURL() + "log/newLogRecorder/?name=" + logNameForAdmin), HttpMethod.POST); - + wc.getOptions().setRedirectEnabled(false); Page page = wc.getPage(request); assertEquals(302, page.getWebResponse().getStatusCode()); assertRequestWasNotBlocked(); - + // after creation the logger exists j.assertGoodStatus(wc.goTo("log/" + logNameForAdmin + "/autoCompleteLoggerName/?value=a", null)); assertRequestWasNotBlocked(); - + assertEquals(404, wc.goTo("log/" + "nonExistingName" + "/autoCompleteLoggerName/?value=a", null).getWebResponse().getStatusCode()); assertRequestWasNotBlocked(); } - + { // user is blocked JenkinsRule.WebClient wc = j.createWebClient(); wc.login("user"); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + // no right to check the existence of a logger assertEquals(403, wc.goTo("log/" + logNameForUser + "/autoCompleteLoggerName/?value=a", null).getWebResponse().getStatusCode()); assertRequestWasNotBlocked(); - + WebRequest request = new WebRequest(new URL(j.getURL() + "log/newLogRecorder/?name=" + logNameForUser), HttpMethod.POST); - + wc.getOptions().setRedirectEnabled(false); Page page = wc.getPage(request); assertEquals(403, page.getWebResponse().getStatusCode()); assertRequestWasNotBlocked(); - + // after the failed attempt, the logger is not created assertEquals(403, wc.goTo("log/" + logNameForUser + "/autoCompleteLoggerName/?value=a", null).getWebResponse().getStatusCode()); assertRequestWasNotBlocked(); } - + { // admin can check the non-existence after user failed creation also - + JenkinsRule.WebClient wc = j.createWebClient(); wc.login("admin"); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + // ensure the logger was not created by the user (check in case the request returned 403 but created the logger silently) assertEquals(404, wc.goTo("log/" + logNameForUser + "/autoCompleteLoggerName/?value=a", null).getWebResponse().getStatusCode()); assertRequestWasNotBlocked(); } } - + @Test public void anonCannotHaveTheListOfUsers() throws Exception { j.jenkins.setCrumbIssuer(null); - + FullControlOnceLoggedInAuthorizationStrategy authorizationStrategy = new FullControlOnceLoggedInAuthorizationStrategy(); j.jenkins.setAuthorizationStrategy(authorizationStrategy); - + HudsonPrivateSecurityRealm securityRealm = new HudsonPrivateSecurityRealm(false, false, null); j.jenkins.setSecurityRealm(securityRealm); securityRealm.createAccount("admin", "admin"); securityRealm.createAccount("secretUser", "secretUser"); - + { // admin should have access to the user list JenkinsRule.WebClient wc = j.createWebClient(); wc.login("admin"); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + Page page = wc.goTo("securityRealm"); assertEquals(200, page.getWebResponse().getStatusCode()); assertThat(page.getWebResponse().getContentAsString(), containsString("secretUser")); assertRequestWasNotBlocked(); } - - // with or without the anonymousRead, anonymous are not allowed to have access to + + // with or without the anonymousRead, anonymous are not allowed to have access to // list of users in securityRealm authorizationStrategy.setAllowAnonymousRead(true); { // without any read permission the anon have access to the user list JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); wc.getOptions().setRedirectEnabled(false); - + Page page = wc.goTo("securityRealm/", null); checkPageIsRedirectedToLogin(page); assertThat(page.getWebResponse().getContentAsString(), not(containsString("secretUser"))); assertRequestWasNotBlocked(); - + page = wc.goTo("asynchPeople/", null); assertEquals(200, page.getWebResponse().getStatusCode()); // javascript will load the user list asynch assertThat(page.getWebResponse().getContentAsString(), containsString("Includes all known")); assertRequestWasNotBlocked(); } - + authorizationStrategy.setAllowAnonymousRead(false); { // and with restriction, the anonymous users cannot read the user list JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); wc.getOptions().setRedirectEnabled(false); - + Page page = wc.goTo("securityRealm/", null); checkPageIsRedirectedToLogin(page); assertThat(page.getWebResponse().getContentAsString(), not(containsString("secretUser"))); assertRequestWasNotBlocked(); - + // with the restriction we disallow the anon to even read the list of all users page = wc.goTo("asynchPeople/", null); checkPageIsRedirectedToLogin(page); @@ -669,7 +669,7 @@ public void anonCannotHaveTheListOfUsers() throws Exception { assertRequestWasNotBlocked(); } } - + @Test @Issue("SECURITY-722") public void noAccessToAllUsers() throws Exception { @@ -677,37 +677,37 @@ public void noAccessToAllUsers() throws Exception { HudsonPrivateSecurityRealm securityRealm = new HudsonPrivateSecurityRealm(false, false, null); j.jenkins.setSecurityRealm(securityRealm); securityRealm.createAccount("admin", "admin"); - + j.jenkins.setAuthorizationStrategy( new MockAuthorizationStrategy() .grant(Jenkins.ADMINISTER).everywhere().to("admin") ); - + { // neither anon have access to the allUsers end point JenkinsRule.WebClient wc = j.createWebClient(); // anonymous user wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + Page page = wc.goTo("securityRealm/allUsers/" + 0 + "/descriptorByName/jenkins.security.ApiTokenProperty/help/apiToken/"); assertEquals(404, page.getWebResponse().getStatusCode()); assertRequestWasBlockedAndResetFlag(); } - + { // nor the admin have that access JenkinsRule.WebClient wc = j.createWebClient(); wc.login("admin"); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + Page page = wc.goTo("securityRealm/allUsers/" + 0 + "/descriptorByName/jenkins.security.ApiTokenProperty/help/apiToken/"); assertEquals(404, page.getWebResponse().getStatusCode()); assertRequestWasBlockedAndResetFlag(); } } - + // // does not work in 2.60 since the method was added in 2.91+ // String newLogin = "newUser"; // j.createWebClient().goTo("securityRealm/allUsers/0/orCreateByIdOrFullName/" + newLogin + "/"); - + private void checkPageIsRedirectedToLogin(Page page) { assertEquals(200, page.getWebResponse().getStatusCode()); assertThat(page.getUrl().getPath(), containsString("login")); diff --git a/test/src/test/java/jenkins/security/stapler/Security867Test.java b/test/src/test/java/jenkins/security/stapler/Security867Test.java index 8d770665d52f..49f4568aae5d 100644 --- a/test/src/test/java/jenkins/security/stapler/Security867Test.java +++ b/test/src/test/java/jenkins/security/stapler/Security867Test.java @@ -41,75 +41,75 @@ public class Security867Test { @Rule public JenkinsRule j = new JenkinsRule(); - + @Test @Issue("SECURITY-867") public void folderTraversalPrevented_avoidStealingSecretInView() throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + String publicContent = "Test OK"; String secretContent = "s3cr3t"; - + // to validate the attack reproduction you can disable the protection // Facet.ALLOW_VIEW_NAME_PATH_TRAVERSAL = true; - + // regular behavior assertThat(getContentAndCheck200(wc, "rootAction1/public"), containsString(publicContent)); - + // malicious usage prevention - + // looking for /jenkins/security/stapler/Security867Test/NotRootAction2/secret - assertThat(getContent(wc, "rootAction1/%2fjenkins%2fsecurity%2fstapler%2fSecurity867Test%2fNotRootAction2%2fsecret"), + assertThat(getContent(wc, "rootAction1/%2fjenkins%2fsecurity%2fstapler%2fSecurity867Test%2fNotRootAction2%2fsecret"), not(containsString(secretContent))); - - // looking for /jenkins\security\stapler\Security867Test\NotRootAction2\secret => + + // looking for /jenkins\security\stapler\Security867Test\NotRootAction2\secret => // absolute path with backslash (initial forward one is required for absolute) - assertThat(getContent(wc,"rootAction1/%2fjenkins%5csecurity%5cstapler%5cSecurity867Test%5cNotRootAction2%5csecret"), + assertThat(getContent(wc,"rootAction1/%2fjenkins%5csecurity%5cstapler%5cSecurity867Test%5cNotRootAction2%5csecret"), not(containsString(secretContent))); - + // looking for ../NotRootAction2/secret => relative path - assertThat(getContent(wc,"rootAction1/%2e%2e%2fNotRootAction2%2fsecret"), + assertThat(getContent(wc,"rootAction1/%2e%2e%2fNotRootAction2%2fsecret"), not(containsString(secretContent))); - + // looking for ..\NotRootAction2\secret => relative path without forward slash assertThat(getContent(wc, "rootAction1/%2e%2e%5cNotRootAction2%5csecret"), not(containsString(secretContent))); } - + private String getContent(JenkinsRule.WebClient wc, String url) throws Exception { Page page = wc.goTo(url, null); return page.getWebResponse().getContentAsString(); } - + private String getContentAndCheck200(JenkinsRule.WebClient wc, String url) throws Exception { Page page = wc.goTo(url, null); assertThat(page.getWebResponse().getStatusCode(), equalTo(200)); return page.getWebResponse().getContentAsString(); } - + @Test @Issue("SECURITY-867") public void folderTraversalPrevented_avoidStealingSecretFromDifferentObject() throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); - + String action1Config = j.jenkins.getExtensionList(RootAction.class).get(RootAction1.class).getMyConfig(); String action3Config = j.jenkins.getExtensionList(RootAction.class).get(RootAction3.class).getMyConfig(); - + // to validate the attack reproduction you can disable the protection // Facet.ALLOW_VIEW_NAME_PATH_TRAVERSAL = true; - + // regular behavior, the config is only displayed in ActionRoot3 assertThat(getContentAndCheck200(wc, "rootAction1/public"), not(containsString(action1Config))); assertThat(getContentAndCheck200(wc, "rootAction3/showConfig"), allOf( containsString(action3Config), not(containsString(action1Config)) )); - + // the main point here is the last node visited will be "it" for the view scope // if we navigate by RootAction1, we pass it to the RootAction3's view - + // malicious usage prevention, looking for ../RootAction3/showConfig => relative path // without the prevention, the config value of RootAction1 will be used here assertThat(getContent(wc, "rootAction1/%2e%2e%2fRootAction3%2fshowConfig"), allOf( @@ -117,7 +117,7 @@ public void folderTraversalPrevented_avoidStealingSecretFromDifferentObject() th not(containsString(action3Config)) )); } - + @TestExtension @StaplerViews("public") public static class RootAction1 implements RootAction { @@ -125,23 +125,23 @@ public static class RootAction1 implements RootAction { public String getMyConfig() { return "config-1"; } - + @Override public @CheckForNull String getIconFileName() { return null; } - + @Override public @CheckForNull String getDisplayName() { return null; } - + @Override public @CheckForNull String getUrlName() { return "rootAction1"; } } - + @TestExtension @StaplerViews("showConfig") public static class RootAction3 implements RootAction { @@ -149,17 +149,17 @@ public static class RootAction3 implements RootAction { public String getMyConfig() { return "config-3"; } - + @Override public @CheckForNull String getIconFileName() { return null; } - + @Override public @CheckForNull String getDisplayName() { return null; } - + @Override public @CheckForNull String getUrlName() { return "rootAction3"; diff --git a/test/src/test/java/jenkins/security/stapler/Security914Test.java b/test/src/test/java/jenkins/security/stapler/Security914Test.java index 3b66d4da6595..64dc114d2777 100644 --- a/test/src/test/java/jenkins/security/stapler/Security914Test.java +++ b/test/src/test/java/jenkins/security/stapler/Security914Test.java @@ -41,18 +41,18 @@ @Issue("SECURITY-914") public class Security914Test { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Test @WithPlugin("credentials.hpi") public void cannotUseInvalidLocale_toTraverseFolder() throws Exception { assumeTrue(Functions.isWindows()); - + assertNotNull(j.getPluginManager().getPlugin("credentials")); j.createWebClient().goTo("plugin/credentials/images/24x24/credentials.png", "image/png"); - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); WebRequest request = new WebRequest(new URL(j.getURL() + "plugin/credentials/.xml")); @@ -60,12 +60,12 @@ public void cannotUseInvalidLocale_toTraverseFolder() throws Exception { // rootDir is in : test\target\jenkinsTests.tmp\jenkins1274934531848159942test // j.jenkins.getRootDir().getName() = jenkins1274934531848159942test request.setAdditionalHeader("Accept-Language", "../../../../jenkinsTests.tmp/" + j.jenkins.getRootDir().getName() + "/config"); - + Page p = wc.getPage(request); assertEquals(HttpURLConnection.HTTP_NOT_FOUND, p.getWebResponse().getStatusCode()); assertNotEquals(p.getWebResponse().getContentType(), "application/xml"); } - + @Test @WithPlugin("credentials.hpi") public void cannotUseInvalidLocale_toAnyFileInSystem() throws Exception { @@ -73,13 +73,13 @@ public void cannotUseInvalidLocale_toAnyFileInSystem() throws Exception { assertNotNull(j.getPluginManager().getPlugin("credentials")); j.createWebClient().goTo("plugin/credentials/images/24x24/credentials.png", "image/png"); - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); WebRequest request = new WebRequest(new URL(j.getURL() + "plugin/credentials/.ini")); // ../ can be multiply to infinity, no impact, we just need to have enough to reach the root request.setAdditionalHeader("Accept-Language", "../../../../../../../../../../../../windows/win"); - + Page p = wc.getPage(request); assertEquals(HttpURLConnection.HTTP_NOT_FOUND, p.getWebResponse().getStatusCode()); assertEquals("text/html", p.getWebResponse().getContentType()); diff --git a/test/src/test/java/jenkins/security/stapler/StaplerAbstractTest.java b/test/src/test/java/jenkins/security/stapler/StaplerAbstractTest.java index 5e0b0405d710..ee87971ef5d2 100644 --- a/test/src/test/java/jenkins/security/stapler/StaplerAbstractTest.java +++ b/test/src/test/java/jenkins/security/stapler/StaplerAbstractTest.java @@ -53,23 +53,23 @@ public abstract class StaplerAbstractTest { @ClassRule public static JenkinsRule rule = new JenkinsRule(); protected JenkinsRule j; - + protected JenkinsRule.WebClient wc; - + protected WebApp webApp; - + protected static boolean filteredGetMethodTriggered = false; protected static boolean filteredDoActionTriggered = false; protected static boolean filteredFieldTriggered = false; - + @Before public void setUp() throws Exception { j = rule; j.jenkins.setCrumbIssuer(null); wc = j.createWebClient(); - + this.webApp = (WebApp) j.jenkins.servletContext.getAttribute(WebApp.class.getName()); - + webApp.setFilteredGetterTriggerListener((f, req, rst, node, expression) -> { filteredGetMethodTriggered = true; return false; @@ -82,52 +82,52 @@ public void setUp() throws Exception { filteredFieldTriggered = true; return false; }); - + filteredGetMethodTriggered = false; filteredDoActionTriggered = false; filteredFieldTriggered = false; } - + //================================= utility class ================================= - + protected static class AbstractUnprotectedRootAction implements UnprotectedRootAction { @Override public @CheckForNull String getIconFileName() { return null; } - + @Override public @CheckForNull String getDisplayName() { return null; } - + @Override public @CheckForNull String getUrlName() { return StringUtils.uncapitalize(this.getClass().getSimpleName()); } } - + public static final String RENDERABLE_CLASS_SIGNATURE = "class jenkins.security.stapler.StaplerAbstractTest.Renderable"; protected static class Renderable { - + public void doIndex() {replyOk();} - + @WebMethod(name = "valid") public void valid() {replyOk();} } - + protected static class ParentRenderable { public Renderable getRenderable(){ return new Renderable(); } } - + protected static class RenderablePoint extends Point { public void doIndex() {replyOk();} } - + //================================= utility methods ================================= - + protected static void replyOk() { StaplerResponse resp = Stapler.getCurrentResponse(); try { @@ -137,9 +137,9 @@ protected static void replyOk() { throw new UncheckedIOException(e); } } - + //================================= testing methods ================================= - + protected void assertGetMethodRequestWasBlockedAndResetFlag() { assertTrue("No get method request was blocked", filteredGetMethodTriggered); filteredGetMethodTriggered = false; @@ -161,13 +161,13 @@ protected void assertDoActionRequestWasNotBlocked() { protected void assertFieldRequestWasNotBlocked() { assertFalse("There was at least one field request that was blocked", filteredFieldTriggered); } - + protected void assertReachable(String url, HttpMethod method) throws IOException { try { Page page = wc.getPage(new WebRequest(new URL(j.getURL(), url), method)); assertEquals(200, page.getWebResponse().getStatusCode()); assertThat(page.getWebResponse().getContentAsString(), startsWith("ok")); - + assertDoActionRequestWasNotBlocked(); assertGetMethodActionRequestWasNotBlocked(); assertFieldRequestWasNotBlocked(); @@ -175,18 +175,18 @@ protected void assertReachable(String url, HttpMethod method) throws IOException throw new AssertionError("Url " + url + " should be reachable, received " + e.getMessage() + " (" + e.getStatusCode() + ") instead.", e); } } - + protected void assertReachable(String url) throws IOException { assertReachable(url, HttpMethod.GET); } - + protected void assertReachableWithSettings(WebRequest request) throws IOException { Page page = wc.getPage(request); assertEquals(200, page.getWebResponse().getStatusCode()); assertEquals("ok", page.getWebResponse().getContentAsString()); assertDoActionRequestWasNotBlocked(); } - + protected void assertReachableWithoutOk(String url) throws IOException { try { Page page = wc.getPage(new URL(j.getURL(), url)); @@ -195,7 +195,7 @@ protected void assertReachableWithoutOk(String url) throws IOException { throw new AssertionError("Url " + url + " should be reachable, received " + e.getMessage() + " (" + e.getStatusCode() + ") instead.", e); } } - + protected void assertNotReachable(String url) throws IOException { FailingHttpStatusCodeException e = assertThrows("Url " + url + " is reachable but should not be, a not-found error is expected", FailingHttpStatusCodeException.class, () -> wc.getPage(new URL(j.getURL(), url))); assertEquals("Url " + url + " returns an error different from 404", 404, e.getResponse().getStatusCode()); diff --git a/test/src/test/java/jenkins/security/stapler/StaticRoutingDecisionProvider2Test.java b/test/src/test/java/jenkins/security/stapler/StaticRoutingDecisionProvider2Test.java index 561adc43881f..8cc1e59daf49 100644 --- a/test/src/test/java/jenkins/security/stapler/StaticRoutingDecisionProvider2Test.java +++ b/test/src/test/java/jenkins/security/stapler/StaticRoutingDecisionProvider2Test.java @@ -41,16 +41,16 @@ import org.jvnet.hudson.test.recipes.LocalData; /** - * Due to the fact we are using a @ClassRule for the other tests to improve performance, + * Due to the fact we are using a @ClassRule for the other tests to improve performance, * we cannot use @LocalData to test the loading of the whitelist as that annotation seem to not work with @ClassRule. */ @Issue("SECURITY-400") @For(StaticRoutingDecisionProvider.class) public class StaticRoutingDecisionProvider2Test { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Test @LocalData("whitelist_empty") public void userControlledWhitelist_empty_Loading() throws Exception { @@ -64,7 +64,7 @@ public void userControlledWhitelist_empty_Loading() throws Exception { is(RoutingDecisionProvider.Decision.UNKNOWN) ); } - + @Test @LocalData("whitelist_monoline") public void userControlledWhitelist_monoline_Loading() throws Exception { @@ -78,7 +78,7 @@ public void userControlledWhitelist_monoline_Loading() throws Exception { is(RoutingDecisionProvider.Decision.UNKNOWN) ); } - + @Test @LocalData("whitelist_multiline") public void userControlledWhitelist_multiline_Loading() throws Exception { @@ -96,7 +96,7 @@ public void userControlledWhitelist_multiline_Loading() throws Exception { is(RoutingDecisionProvider.Decision.UNKNOWN) ); } - + @Test @LocalData("comment_ignored") public void userControlledWhitelist_commentsAreIgnored() throws Exception { @@ -105,11 +105,11 @@ public void userControlledWhitelist_commentsAreIgnored() throws Exception { assertThat(wl.decide("not-this-one"), is(RoutingDecisionProvider.Decision.UNKNOWN)); assertThat(wl.decide("neither"), is(RoutingDecisionProvider.Decision.UNKNOWN)); assertThat(wl.decide("finally-not"), is(RoutingDecisionProvider.Decision.UNKNOWN)); - + assertThat(wl.decide("this-one-is"), is(RoutingDecisionProvider.Decision.ACCEPTED)); assertThat(wl.decide("this-one-also"), is(RoutingDecisionProvider.Decision.ACCEPTED)); } - + @Test @LocalData("whitelist_emptyline") public void userControlledWhitelist_emptyLinesAreIgnored() throws Exception { @@ -120,25 +120,25 @@ public void userControlledWhitelist_emptyLinesAreIgnored() throws Exception { // neither the empty line or an exclamation mark followed by nothing or spaces are not considered assertThat(wl.decide(""), is(RoutingDecisionProvider.Decision.UNKNOWN)); } - + @Test @LocalData("greylist_multiline") public void userControlledWhitelist_whiteAndBlack() throws Exception { StaticRoutingDecisionProvider wl = new StaticRoutingDecisionProvider(); assertThat(wl.decide("signature-1-ok"), is(RoutingDecisionProvider.Decision.ACCEPTED)); assertThat(wl.decide("signature-3-ok"), is(RoutingDecisionProvider.Decision.ACCEPTED)); - + assertThat(wl.decide("signature-2-not-ok"), is(RoutingDecisionProvider.Decision.REJECTED)); assertThat(wl.decide("signature-4-not-ok"), is(RoutingDecisionProvider.Decision.REJECTED)); - + // the exclamation mark is not used assertThat(wl.decide("!signature-2-not-ok"), is(RoutingDecisionProvider.Decision.UNKNOWN)); } - + @Test public void defaultList() throws Exception { StaticRoutingDecisionProvider wl = new StaticRoutingDecisionProvider(); - + assertThat( wl.decide("method io.jenkins.blueocean.service.embedded.rest.AbstractRunImpl getLog"), is(RoutingDecisionProvider.Decision.ACCEPTED) @@ -151,7 +151,7 @@ public void defaultList() throws Exception { wl.decide("method io.jenkins.blueocean.rest.impl.pipeline.PipelineStepImpl getLog"), is(RoutingDecisionProvider.Decision.ACCEPTED) ); - + assertThat(wl.decide("method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ContentProvider getObjectCustom"), is(RoutingDecisionProvider.Decision.UNKNOWN) ); @@ -159,73 +159,73 @@ public void defaultList() throws Exception { is(RoutingDecisionProvider.Decision.UNKNOWN) ); } - + @Test public void userControlledWhitelist_savedCorrectly() throws Exception { File whitelistUserControlledList = new File(j.jenkins.getRootDir(), "stapler-whitelist.txt"); - + assertFalse(whitelistUserControlledList.exists()); - + StaticRoutingDecisionProvider wl = new StaticRoutingDecisionProvider(); - + assertFalse(whitelistUserControlledList.exists()); - + assertThat(wl.decide("nothing"), is(RoutingDecisionProvider.Decision.UNKNOWN)); - + wl.save(); assertTrue(whitelistUserControlledList.exists()); assertThat(FileUtils.readFileToString(whitelistUserControlledList), is("")); - + wl.add("white-1"); - + assertThat(wl.decide("white-1"), is(RoutingDecisionProvider.Decision.ACCEPTED)); - + assertTrue(whitelistUserControlledList.exists()); assertThat(FileUtils.readFileToString(whitelistUserControlledList), containsString("white-1")); { StaticRoutingDecisionProvider temp = new StaticRoutingDecisionProvider(); assertThat(temp.decide("white-1"), is(RoutingDecisionProvider.Decision.ACCEPTED)); } - + wl.addBlacklistSignature("black-2"); - + assertThat(wl.decide("white-1"), is(RoutingDecisionProvider.Decision.ACCEPTED)); assertThat(wl.decide("black-2"), is(RoutingDecisionProvider.Decision.REJECTED)); assertThat(FileUtils.readFileToString(whitelistUserControlledList), allOf( containsString("white-1"), containsString("!black-2") )); - + { StaticRoutingDecisionProvider temp = new StaticRoutingDecisionProvider(); assertThat(temp.decide("white-1"), is(RoutingDecisionProvider.Decision.ACCEPTED)); assertThat(temp.decide("black-2"), is(RoutingDecisionProvider.Decision.REJECTED)); } - + wl.removeBlacklistSignature("black-2"); - + assertThat(wl.decide("white-1"), is(RoutingDecisionProvider.Decision.ACCEPTED)); assertThat(wl.decide("black-2"), is(RoutingDecisionProvider.Decision.UNKNOWN)); assertThat(FileUtils.readFileToString(whitelistUserControlledList), allOf( containsString("white-1"), not(containsString("black-2")) )); - + { StaticRoutingDecisionProvider temp = new StaticRoutingDecisionProvider(); assertThat(temp.decide("white-1"), is(RoutingDecisionProvider.Decision.ACCEPTED)); assertThat(temp.decide("black-2"), is(RoutingDecisionProvider.Decision.UNKNOWN)); } - + wl.remove("white-1"); - + assertThat(wl.decide("white-1"), is(RoutingDecisionProvider.Decision.UNKNOWN)); assertThat(wl.decide("black-2"), is(RoutingDecisionProvider.Decision.UNKNOWN)); assertThat(FileUtils.readFileToString(whitelistUserControlledList), allOf( not(containsString("white-1")), not(containsString("black-2")) )); - + { StaticRoutingDecisionProvider temp = new StaticRoutingDecisionProvider(); assertThat(temp.decide("white-1"), is(RoutingDecisionProvider.Decision.UNKNOWN)); diff --git a/test/src/test/java/jenkins/security/stapler/StaticRoutingDecisionProviderTest.java b/test/src/test/java/jenkins/security/stapler/StaticRoutingDecisionProviderTest.java index 6981631498eb..8fda8b2579b0 100644 --- a/test/src/test/java/jenkins/security/stapler/StaticRoutingDecisionProviderTest.java +++ b/test/src/test/java/jenkins/security/stapler/StaticRoutingDecisionProviderTest.java @@ -49,23 +49,23 @@ public static class ContentProvider extends AbstractUnprotectedRootAction { // simulate side effect public static boolean called = false; public static boolean called2 = false; - + public FreeStyleProject getJob() { called = true; return (FreeStyleProject) Jenkins.get().getItem("testProject"); } - + public String getString() { called = true; return "a"; } - + // cannot provide side-effect since the String has no side-effect methods public Object getObjectString() { called = true; return "a"; } - + public static String OBJECT_CUSTOM_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ContentProvider getObjectCustom"; // but it opens wide range of potentially dangerous classes @@ -80,43 +80,43 @@ public void doIndex() { }; } } - + @Before public void preparation() throws Exception { ContentProvider.called = false; ContentProvider.called2 = false; } - + @Before public void resetWhitelist() throws Exception { ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).resetAndSave(); } - + @Test public void test_job_index() throws Exception { j.createFreeStyleProject("testProject"); assertReachableWithoutOk("contentProvider/job/"); assertTrue(ContentProvider.called); } - + @Test public void test_string() throws Exception { assertNotReachable("contentProvider/string/"); assertFalse(ContentProvider.called); } - + @Test public void test_objectString() throws Exception { assertNotReachable("contentProvider/objectString/"); assertFalse(ContentProvider.called); } - + @Test public void test_objectCustom() throws Exception { assertNotReachable("contentProvider/objectCustom/"); assertFalse(ContentProvider.called); } - + //for more test about the whitelist initial loading, please refer to StaticRoutingDecisionProvider2Test @Test public void test_objectCustom_withUserControlledSavedWhitelist() throws Throwable { @@ -135,7 +135,7 @@ public void test_objectCustom_withUserControlledSavedWhitelist() throws Throwabl ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).reload(); } } - + @Test public void test_objectCustom_withUserControlledEditedWhitelist() throws Exception { try { @@ -143,23 +143,23 @@ public void test_objectCustom_withUserControlledEditedWhitelist() throws Excepti assertFalse(ContentProvider.called); assertNotReachable("contentProvider/objectCustom/"); assertFalse(ContentProvider.called); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).add(ContentProvider.OBJECT_CUSTOM_SIGNATURE); - + assertNotReachable("contentProvider/objectString/"); assertFalse(ContentProvider.called); assertFalse(ContentProvider.called2); assertGetMethodRequestWasBlockedAndResetFlag(); - + assertReachable("contentProvider/objectCustom/"); assertTrue(ContentProvider.called); assertTrue(ContentProvider.called2); - + ContentProvider.called = false; ContentProvider.called2 = false; - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).remove(ContentProvider.OBJECT_CUSTOM_SIGNATURE); - + assertNotReachable("contentProvider/objectString/"); assertFalse(ContentProvider.called); assertNotReachable("contentProvider/objectCustom/"); @@ -169,7 +169,7 @@ public void test_objectCustom_withUserControlledEditedWhitelist() throws Excepti ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).reload(); } } - + @Test public void test_objectCustom_withStandardWhitelist() throws Exception { assertNotReachable("contentProvider/objectString/"); @@ -177,23 +177,23 @@ public void test_objectCustom_withStandardWhitelist() throws Exception { assertGetMethodRequestWasBlockedAndResetFlag(); assertNotReachable("contentProvider/objectCustom/"); assertFalse(ContentProvider.called); - + StaticRoutingDecisionProvider whitelist = ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class); - + {// add entry in the set loaded from the standard whitelist file and reload Method resetMetaClassCache = StaticRoutingDecisionProvider.class.getDeclaredMethod("resetMetaClassCache"); resetMetaClassCache.setAccessible(true); - + Field field = StaticRoutingDecisionProvider.class.getDeclaredField("whitelistSignaturesFromFixedList"); field.setAccessible(true); @SuppressWarnings("unchecked") Set standardWhitelist = (Set) field.get(whitelist); - + standardWhitelist.add(ContentProvider.OBJECT_CUSTOM_SIGNATURE); // just call this method to avoid to reload the file and so override our new signature resetMetaClassCache.invoke(whitelist); } - + assertNotReachable("contentProvider/objectString/"); assertFalse(ContentProvider.called); assertFalse(ContentProvider.called2); @@ -201,156 +201,156 @@ public void test_objectCustom_withStandardWhitelist() throws Exception { assertReachable("contentProvider/objectCustom/"); assertTrue(ContentProvider.called); assertTrue(ContentProvider.called2); - + {// reset to previous state ContentProvider.called = false; ContentProvider.called2 = false; - + whitelist.reload(); } - + assertNotReachable("contentProvider/objectString/"); assertFalse(ContentProvider.called); assertNotReachable("contentProvider/objectCustom/"); assertFalse(ContentProvider.called); } - + @TestExtension public static class ActionWithWhitelist extends AbstractUnprotectedRootAction { @Override public @CheckForNull String getUrlName() { return "do-action"; } - + public static String DO_ACTION_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ActionWithWhitelist doAction org.kohsuke.stapler.StaplerRequest"; - + public void doAction(StaplerRequest request) { replyOk(); } - + public static String DO_ACTION_STAPLER_ROUTABLE_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ActionWithWhitelist doActionWithStaplerDispatchable org.kohsuke.stapler.StaplerRequest"; - + @StaplerDispatchable public void doActionWithStaplerDispatchable(StaplerRequest request) { replyOk(); } - + public static String DO_ACTION_STAPLER_NONROUTABLE_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ActionWithWhitelist doActionWithStaplerNotDispatchable org.kohsuke.stapler.StaplerRequest"; - + @StaplerNotDispatchable public void doActionWithStaplerNotDispatchable(StaplerRequest request) { replyOk(); } - + public static String DO_ACTION_STAPLER_WEBMETHOD_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ActionWithWhitelist doActionWithWebMethod org.kohsuke.stapler.StaplerRequest"; - + @WebMethod(name = "actionWithWebMethod") public void doActionWithWebMethod(StaplerRequest request) { replyOk(); } } - + @Test public void doAction_regular() throws Exception { assertReachable("do-action/action/"); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).add(ActionWithWhitelist.DO_ACTION_SIGNATURE); - + assertReachable("do-action/action/"); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).remove(ActionWithWhitelist.DO_ACTION_SIGNATURE); - + assertReachable("do-action/action/"); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).addBlacklistSignature(ActionWithWhitelist.DO_ACTION_SIGNATURE); - + assertNotReachable("do-action/action/"); assertDoActionRequestWasBlockedAndResetFlag(); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).removeBlacklistSignature(ActionWithWhitelist.DO_ACTION_SIGNATURE); - + assertReachable("do-action/action/"); } - + @Test public void doAction_actionWithStaplerDispatchable() throws Exception { assertReachable("do-action/actionWithStaplerDispatchable/"); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).addBlacklistSignature(ActionWithWhitelist.DO_ACTION_STAPLER_ROUTABLE_SIGNATURE); - + assertReachable("do-action/actionWithStaplerDispatchable/"); } - + @Test public void doAction_actionWithWebMethod() throws Exception { assertReachable("do-action/actionWithWebMethod/"); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).addBlacklistSignature(ActionWithWhitelist.DO_ACTION_STAPLER_WEBMETHOD_SIGNATURE); - + assertNotReachable("do-action/actionWithWebMethod/"); assertDoActionRequestWasBlockedAndResetFlag(); } - + @TestExtension public static class GetterWithWhitelist extends AbstractUnprotectedRootAction { @Override public @CheckForNull String getUrlName() { return "getter"; } - + public static String GET_ITEM_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$GetterWithWhitelist getItem"; - + public Renderable getItem() { return new Renderable(); } - + public static String GET_ITEM_STAPLER_ROUTABLE_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$GetterWithWhitelist getItemWithStaplerDispatchable"; - + @StaplerDispatchable public Renderable getItemWithStaplerDispatchable() { return new Renderable(); } - + public static String GET_ITEM_STAPLER_NONROUTABLE_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$GetterWithWhitelist getItemWithStaplerNotDispatchable"; - + @StaplerNotDispatchable public Renderable getItemWithStaplerNotDispatchable() { return new Renderable(); } } - + @Test public void getItem_regular() throws Exception { assertReachable("getter/item/"); assertReachable("getter/item/valid"); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).addBlacklistSignature(GetterWithWhitelist.GET_ITEM_SIGNATURE); - + assertNotReachable("getter/item/"); assertGetMethodRequestWasBlockedAndResetFlag(); assertNotReachable("getter/item/valid"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @Test public void getItem_getterWithStaplerDispatchable() throws Exception { assertReachable("getter/itemWithStaplerDispatchable/"); assertReachable("getter/itemWithStaplerDispatchable/valid"); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).addBlacklistSignature(GetterWithWhitelist.GET_ITEM_STAPLER_ROUTABLE_SIGNATURE); // Annotation overrides whitelist/blacklist assertReachable("getter/itemWithStaplerDispatchable/"); assertReachable("getter/itemWithStaplerDispatchable/valid"); } - + @Test public void getItem_getterWithStaplerNotDispatchable() throws Exception { assertNotReachable("getter/itemWithStaplerNotDispatchable/"); assertGetMethodRequestWasBlockedAndResetFlag(); assertNotReachable("getter/itemWithStaplerNotDispatchable/valid"); assertGetMethodRequestWasBlockedAndResetFlag(); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).add(GetterWithWhitelist.GET_ITEM_STAPLER_NONROUTABLE_SIGNATURE); // Annotation overrides whitelist/blacklist @@ -359,110 +359,110 @@ public void getItem_getterWithStaplerNotDispatchable() throws Exception { assertNotReachable("getter/itemWithStaplerNotDispatchable/valid"); assertGetMethodRequestWasBlockedAndResetFlag(); } - + @TestExtension public static class FieldWithWhitelist extends AbstractUnprotectedRootAction { @Override public @CheckForNull String getUrlName() { return "field"; } - + public static String FIELD_SIGNATURE = "field jenkins.security.stapler.StaticRoutingDecisionProviderTest$FieldWithWhitelist renderable"; - + public Renderable renderable = new Renderable(); - + public static String FIELD_STAPLER_ROUTABLE_SIGNATURE = "field jenkins.security.stapler.StaticRoutingDecisionProviderTest$FieldWithWhitelist renderableWithStaplerDispatchable"; - + @StaplerDispatchable public Renderable renderableWithStaplerDispatchable = new Renderable(); - + public static String FIELD_STAPLER_NONROUTABLE_SIGNATURE = "field jenkins.security.stapler.StaticRoutingDecisionProviderTest$FieldWithWhitelist renderableWithStaplerNotDispatchable"; - + @StaplerNotDispatchable public Renderable renderableWithStaplerNotDispatchable = new Renderable(); - + public static String FIELD_STATIC_SIGNATURE = "staticField jenkins.security.stapler.StaticRoutingDecisionProviderTest$FieldWithWhitelist staticRenderable"; - + public static Renderable staticRenderable = new Renderable(); - + public static String FIELD_STATIC_STAPLER_ROUTABLE_SIGNATURE = "staticField jenkins.security.stapler.StaticRoutingDecisionProviderTest$FieldWithWhitelist staticRenderableWithStaplerDispatchable"; - + @StaplerDispatchable public static Renderable staticRenderableWithStaplerDispatchable = new Renderable(); - + public static String FIELD_STATIC_STAPLER_NONROUTABLE_SIGNATURE = "staticField jenkins.security.stapler.StaticRoutingDecisionProviderTest$FieldWithWhitelist staticRenderableWithStaplerNotDispatchable"; - + @StaplerNotDispatchable public static Renderable staticRenderableWithStaplerNotDispatchable = new Renderable(); } - + @Test public void field_regular() throws Exception { assertReachable("field/renderable/"); assertReachable("field/renderable/valid"); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).addBlacklistSignature(FieldWithWhitelist.FIELD_SIGNATURE); - + assertNotReachable("field/renderable/"); assertFieldRequestWasBlockedAndResetFlag(); assertNotReachable("field/renderable/valid"); assertFieldRequestWasBlockedAndResetFlag(); } - + @Test public void field_regular_returnType() throws Exception { assertReachable("field/renderable/"); assertReachable("field/renderable/valid"); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).addBlacklistSignature(RENDERABLE_CLASS_SIGNATURE); - + assertNotReachable("field/renderable/"); assertFieldRequestWasBlockedAndResetFlag(); assertNotReachable("field/renderable/valid"); assertFieldRequestWasBlockedAndResetFlag(); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).removeBlacklistSignature(RENDERABLE_CLASS_SIGNATURE); - + assertReachable("field/renderable/"); assertReachable("field/renderable/valid"); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).add(RENDERABLE_CLASS_SIGNATURE); // method is checked first as it's more specific ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).addBlacklistSignature(FieldWithWhitelist.FIELD_SIGNATURE); - + assertNotReachable("field/renderable/"); assertFieldRequestWasBlockedAndResetFlag(); assertNotReachable("field/renderable/valid"); assertFieldRequestWasBlockedAndResetFlag(); - + // reverse, now we blacklist the type but whitelist the method => it's ok ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).remove(RENDERABLE_CLASS_SIGNATURE); ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).removeBlacklistSignature(FieldWithWhitelist.FIELD_SIGNATURE); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).addBlacklistSignature(RENDERABLE_CLASS_SIGNATURE); ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).add(FieldWithWhitelist.FIELD_SIGNATURE); - + assertReachable("field/renderable/"); assertReachable("field/renderable/valid"); } - + @Test public void field_withStaplerDispatchable() throws Exception { assertReachable("field/renderableWithStaplerDispatchable/"); assertReachable("field/renderableWithStaplerDispatchable/valid"); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).addBlacklistSignature(FieldWithWhitelist.FIELD_STAPLER_ROUTABLE_SIGNATURE); assertReachable("field/renderableWithStaplerDispatchable/"); } - + @Test public void field_withStaplerNotDispatchable() throws Exception { assertNotReachable("field/renderableWithStaplerNotDispatchable/"); assertFieldRequestWasBlockedAndResetFlag(); assertNotReachable("field/renderableWithStaplerNotDispatchable/valid"); assertFieldRequestWasBlockedAndResetFlag(); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).add(FieldWithWhitelist.FIELD_STAPLER_NONROUTABLE_SIGNATURE); assertNotReachable("field/renderableWithStaplerNotDispatchable/"); @@ -470,20 +470,20 @@ public void field_withStaplerNotDispatchable() throws Exception { assertNotReachable("field/renderableWithStaplerNotDispatchable/valid"); assertFieldRequestWasBlockedAndResetFlag(); } - + @Test public void fieldStatic_regular() throws Exception { assertNotReachable("field/staticRenderable/"); assertFieldRequestWasBlockedAndResetFlag(); assertNotReachable("field/staticRenderable/valid"); assertFieldRequestWasBlockedAndResetFlag(); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).add(FieldWithWhitelist.FIELD_STATIC_SIGNATURE); assertReachable("field/staticRenderable/"); assertReachable("field/staticRenderable/valid"); } - + @Test public void fieldStatic_withStaplerDispatchable() throws Exception { assertReachable("field/staticRenderableWithStaplerDispatchable/"); @@ -494,16 +494,16 @@ public void fieldStatic_withStaplerDispatchable() throws Exception { assertReachable("field/staticRenderableWithStaplerDispatchable/"); } - + @Test public void fieldStatic_withStaplerNotDispatchable() throws Exception { assertNotReachable("field/staticRenderableWithStaplerNotDispatchable/"); assertFieldRequestWasBlockedAndResetFlag(); assertNotReachable("field/staticRenderableWithStaplerNotDispatchable/valid"); assertFieldRequestWasBlockedAndResetFlag(); - + ExtensionList.lookupSingleton(StaticRoutingDecisionProvider.class).add(FieldWithWhitelist.FIELD_STATIC_STAPLER_NONROUTABLE_SIGNATURE); - + assertNotReachable("field/staticRenderableWithStaplerNotDispatchable/"); assertFieldRequestWasBlockedAndResetFlag(); assertNotReachable("field/staticRenderableWithStaplerNotDispatchable/valid"); diff --git a/test/src/test/java/jenkins/util/SystemPropertiesTest.java b/test/src/test/java/jenkins/util/SystemPropertiesTest.java index 04ea2bbcb18b..86d2e7753172 100644 --- a/test/src/test/java/jenkins/util/SystemPropertiesTest.java +++ b/test/src/test/java/jenkins/util/SystemPropertiesTest.java @@ -41,28 +41,28 @@ * @author Oleg Nenashev */ public class SystemPropertiesTest { - + @Rule public JenkinsRule j = new JenkinsRule(); - + @Before public void setUp() { new SystemProperties.Listener().contextInitialized(new ServletContextEvent(j.jenkins.servletContext)); } - + @Test public void shouldReturnNullIfUndefined() throws Exception { - assertThat("Properties should be null by default", + assertThat("Properties should be null by default", SystemProperties.getString("foo.bar"), nullValue()); } - + @Test public void shouldInitializeFromSystemProperty() throws Exception { System.setProperty("foo.bar", "myVal"); - assertThat("System property should assign the value", + assertThat("System property should assign the value", SystemProperties.getString("foo.bar"), equalTo("myVal")); } - + @Test public void shouldInitializeFromWebAppProperty() throws Exception { assertThat("Property is undefined before test", @@ -76,7 +76,7 @@ public void shouldInitializeFromWebAppProperty() throws Exception { public void shouldUseSystemPropertyAsAHighPriority() throws Exception { setWebAppInitParameter("install-wizard-path", "myVal1"); System.setProperty("install-wizard-path", "myVal2"); - assertThat("System property should take system property with a high priority", + assertThat("System property should take system property with a high priority", SystemProperties.getString("install-wizard-path"), equalTo("myVal2")); } diff --git a/test/src/test/java/jenkins/widgets/BuildTimeTrendTest.java b/test/src/test/java/jenkins/widgets/BuildTimeTrendTest.java index ac1c3e2579b6..456db33d2ada 100644 --- a/test/src/test/java/jenkins/widgets/BuildTimeTrendTest.java +++ b/test/src/test/java/jenkins/widgets/BuildTimeTrendTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2020, CloudBees, Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -105,7 +105,7 @@ public void withAbstractJob_OnBoth() throws Exception { p.setAssignedNode(j.jenkins); j.buildAndAssertSuccess(p); - + p.setAssignedNode(agent); j.buildAndAssertSuccess(p); @@ -156,10 +156,10 @@ public void withNonAbstractJob_withAgents() throws Exception { assumeFalse("TODO: Windows container agents do not have enough resources to run this test", Functions.isWindows() && System.getenv("CI") != null); // just to trigger data-is-distributed-build-enabled = true j.createSlave(); - + // Before the correction, if there was an agent and the build was not inheriting from AbstractBuild, we got // Uncaught TypeError: Cannot read property 'escapeHTML' of undefined - + JenkinsRule.WebClient wc = j.createWebClient(); TopLevelItem p = j.jenkins.getItem("job0"); assertThat(p, instanceOf(NonAbstractJob.class)); @@ -189,14 +189,14 @@ public NonAbstractJob(ItemGroup parent, String name) { super(parent, name); } - @Override + @Override public boolean isBuildable() { return true; } private RunMap runMap; - - @Override + + @Override protected SortedMap _getRuns() { if (runMap == null){ runMap = new RunMap<>(this.getBuildDir(), this::createBuildFromDir); @@ -211,19 +211,19 @@ private NonAbstractBuild createBuildFromDir(File dir) throws IOException { return build; } - @Override + @Override protected void removeRun(NonAbstractBuild run) { - + } - @Override + @Override public DescriptorImpl getDescriptor() { return (NonAbstractJob.DescriptorImpl) Jenkins.get().getDescriptorOrDie(getClass()); } @TestExtension public static class DescriptorImpl extends TopLevelItemDescriptor { - @Override + @Override public TopLevelItem newInstance(ItemGroup parent, String name) { return new NonAbstractJob(parent, name); } diff --git a/test/src/test/java/lib/form/ComboBoxTest.java b/test/src/test/java/lib/form/ComboBoxTest.java index 88fdcab59267..f1ffe4b7c0f3 100644 --- a/test/src/test/java/lib/form/ComboBoxTest.java +++ b/test/src/test/java/lib/form/ComboBoxTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2013 Software in the Public Interest - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -61,13 +61,13 @@ public class ComboBoxTest { public static class CompoundFieldComboBoxBuilder extends Publisher { private CompoundField compoundField; private String foo; - + @DataBoundConstructor public CompoundFieldComboBoxBuilder(CompoundField compoundField, String foo) { this.compoundField = compoundField; this.foo = foo; } - + @Extension public static final class DescriptorImpl extends BuildStepDescriptor { @Override @@ -76,7 +76,7 @@ public boolean isApplicable(Class jobType) { } public ComboBoxModel doFillFooItems( - @QueryParameter @RelativePath("compoundField") String abc, + @QueryParameter @RelativePath("compoundField") String abc, @QueryParameter @RelativePath("compoundField") String xyz) { if (abc == null || xyz == null) { throw new Error("doFillFooItems is broken"); @@ -116,7 +116,7 @@ public String getAbc() { public String getXyz() { return xyz; } - + @Extension public static final class DescriptorImpl extends Descriptor {} } @@ -135,7 +135,7 @@ public void testCompoundFieldDependentComboBox() throws Exception { p.getPublishersList().add(new CompoundFieldComboBoxBuilder(new CompoundField("AABBCC", "XXYYZZ"), null)); try { j.createWebClient().getPage(p,"configure"); - + } catch(AssertionError e) { if(e.getMessage().contains("doFillFooItems is broken")) { fail("Nested field values required for prefill were null"); diff --git a/test/src/test/java/lib/form/ExpandableTextboxTest.java b/test/src/test/java/lib/form/ExpandableTextboxTest.java index 15fd8bfd1003..0b5367fc809e 100644 --- a/test/src/test/java/lib/form/ExpandableTextboxTest.java +++ b/test/src/test/java/lib/form/ExpandableTextboxTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Yahoo! Inc. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -58,7 +58,7 @@ public class ExpandableTextboxTest { @Rule public JenkinsRule j = new JenkinsRule(); - + @Issue("JENKINS-2816") @Test public void testMultiline() throws Exception { @@ -83,65 +83,65 @@ protected HtmlPage evaluateAsHtml(String jellyScript) throws Exception { Page page = wc.getPage(req); return (HtmlPage) page; } - + @Test public void noInjectionArePossible() throws Exception { TestRootAction testParams = j.jenkins.getExtensionList(UnprotectedRootAction.class).get(TestRootAction.class); assertNotNull(testParams); - + checkRegularCase(testParams); checkInjectionInName(testParams); } - + private void checkRegularCase(TestRootAction testParams) throws Exception { testParams.paramName = "testName"; - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); HtmlPage p = wc.goTo("test"); - + HtmlElementUtil.click(getExpandButton(p)); assertNotEquals("hacked", p.getTitleText()); } - + private void checkInjectionInName(TestRootAction testParams) throws Exception { testParams.paramName = "testName',document.title='hacked'+'"; - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); HtmlPage p = wc.goTo("test"); - + HtmlElementUtil.click(getExpandButton(p)); assertNotEquals("hacked", p.getTitleText()); } - + private HtmlButtonInput getExpandButton(HtmlPage page){ DomNodeList buttons = page.getElementById("test-panel").getElementsByTagName("input"); // the first one is the text input assertEquals(2, buttons.size()); return (HtmlButtonInput) buttons.get(1); } - + @TestExtension("noInjectionArePossible") public static final class TestRootAction implements UnprotectedRootAction { - + public String paramName; - + @Override public @CheckForNull String getIconFileName() { return null; } - + @Override public @CheckForNull String getDisplayName() { return null; } - + @Override public String getUrlName() { return "test"; } - + @WebMethod(name = "submit") public HttpResponse doSubmit(StaplerRequest request) { return HttpResponses.plainText("method:" + request.getMethod()); diff --git a/test/src/test/java/lib/form/HeteroListTest.java b/test/src/test/java/lib/form/HeteroListTest.java index cd6d5f7b0a72..4491944ba565 100644 --- a/test/src/test/java/lib/form/HeteroListTest.java +++ b/test/src/test/java/lib/form/HeteroListTest.java @@ -84,7 +84,7 @@ public void xssPrevented_heteroList_usingDescriptorDisplayName() throws Exceptio // correspond to the hardening of escapeEntryTitleAndDescription @Test - @Issue("SECURITY-2035") + @Issue("SECURITY-2035") public void xssPrevented_usingToolInstallation_withJustDisplayName() throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); @@ -93,7 +93,7 @@ public void xssPrevented_usingToolInstallation_withJustDisplayName() throws Exce // check the displayName Object resultDN = page.executeJavaScript( "var settingFields = document.querySelectorAll('.jenkins-form-label');" + - "var children = Array.from(settingFields).filter(b => b.textContent.indexOf('XSS:') !== -1)[0].children;" + + "var children = Array.from(settingFields).filter(b => b.textContent.indexOf('XSS:') !== -1)[0].children;" + "Array.from(children).filter(c => c.tagName === 'IMG')" ).getJavaScriptResult(); assertThat(resultDN, instanceOf(NativeArray.class)); @@ -186,10 +186,10 @@ public void xssPrevented_usingToolInstallation_repeatableAddWithExistingAfterOpe for (String str : resultList) { assertThat(str, not(containsString("<"))); } - + // "delete" then "add" makes us coming back in scenario covered by xssUsingToolInstallationRepeatableAdd } - + @Test @Issue("SECURITY-2035") public void xssPrevented_usingToolInstallation_repeatableDelete() throws Exception { diff --git a/test/src/test/java/lib/form/RepeatablePropertyTest.java b/test/src/test/java/lib/form/RepeatablePropertyTest.java index 3330db2936a5..64c942b05b7d 100644 --- a/test/src/test/java/lib/form/RepeatablePropertyTest.java +++ b/test/src/test/java/lib/form/RepeatablePropertyTest.java @@ -60,9 +60,9 @@ public class RepeatablePropertyTest { private static final String VIEW_WITHOUT_DEFAULT = "noDefault"; private static final String VIEW_WITH_DEFAULT = "withDefault"; - + private RootActionImpl rootAction; - + @Before public void setUp() { rootAction = ExtensionList.lookupSingleton(RootActionImpl.class); @@ -73,18 +73,18 @@ public void testSimple() throws Exception { rootAction.testRepeatable = createRepeatable(); assertFormContents(VIEW_WITHOUT_DEFAULT, rootAction.testRepeatable); } - + @Test public void testNullFieldNoDefault() throws Exception { assertFormContents(VIEW_WITHOUT_DEFAULT, new ArrayList<>()); } - + @Test public void testNullFieldWithDefault() throws Exception { rootAction.defaults = createRepeatable(); assertFormContents(VIEW_WITH_DEFAULT, rootAction.defaults); } - + @Test public void testFieldNotNullWithDefaultIgnoresDefaults() throws Exception { rootAction.testRepeatable = createRepeatable(); @@ -117,7 +117,7 @@ public void testNestedRepeatableProperty() throws Exception { assertEquals(1, containerNameInputs.size()); assertEquals(0, greatPropertyInputs.size()); } - + private void assertFormContents(final String viewName, final ArrayList expected) throws Exception { final HtmlForm form = getForm(viewName); final List inputs = toTextInputList(form.getElementsByAttribute("input", "type", "text")); @@ -125,7 +125,7 @@ private void assertFormContents(final String viewName, final ArrayList toTextInputList(final List inputs) { assertNotNull(inputs); final List textInputList = new ArrayList<>(); @@ -135,7 +135,7 @@ private List toTextInputList(final List inputs) { } return textInputList; } - + private ArrayList createRepeatable() { return new ArrayList<>(Arrays.asList( new ExcitingObject("A nice thing"), diff --git a/test/src/test/java/lib/form/RepeatableTest.java b/test/src/test/java/lib/form/RepeatableTest.java index bafa499657ae..85d2846ea931 100644 --- a/test/src/test/java/lib/form/RepeatableTest.java +++ b/test/src/test/java/lib/form/RepeatableTest.java @@ -111,7 +111,7 @@ public void testSimpleCheckNumberOfButtons() throws Exception { waitForJavaScript(p); assertEquals(1, getButtonsList(f, buttonCaption).size()); // check that only one Add button is in form } - + /** * Test count of buttons in form */ @@ -190,7 +190,7 @@ public void testMinimum_ExistingData() throws Exception { + "{\"bool\":true,\"txt\":\"existing two\"},{\"bool\":false,\"txt\":\"new one\"}]", rootAction.formData.get("foos")); } - + @Test public void testNoData() throws Exception { rootAction.list = null; @@ -201,33 +201,33 @@ public void testNoData() throws Exception { gotoAndSubmitConfig("defaultForItems"); assertNull(rootAction.formData.get("list")); } - + @Test public void testItemsWithDefaults() throws Exception { assertWithDefaults("defaultForItems"); - } + } @Test public void testItemsDefaultsIgnoredIfFieldHasData() throws Exception { assertDefaultsIgnoredIfHaveData("defaultForItems"); - } + } @Test public void testFieldWithDefaults() throws Exception { assertWithDefaults("defaultForField"); - } + } @Test public void testFieldDefaultsIgnoredIfFieldHasData() throws Exception { assertDefaultsIgnoredIfHaveData("defaultForField"); - } + } private void addDefaults() { rootAction.defaults = new ArrayList<>(); rootAction.defaults.add(new Foo("default one", true)); rootAction.defaults.add(new Foo("default two", false)); } - + private void assertWithDefaults(final String viewName) throws Exception { rootAction.list = null; addDefaults(); @@ -235,7 +235,7 @@ private void assertWithDefaults(final String viewName) throws Exception { assertNotNull(rootAction.formData.get("list")); assertEqualsJsonArray("[{\"bool\":true,\"txt\":\"default one\"},{\"bool\":false,\"txt\":\"default two\"}]", rootAction.formData.get("list")); - } + } private void assertDefaultsIgnoredIfHaveData(final String viewName) throws Exception { addData(); @@ -245,7 +245,7 @@ private void assertDefaultsIgnoredIfHaveData(final String viewName) throws Excep assertEqualsJsonArray("[{\"bool\":true,\"txt\":\"existing one\"},{\"bool\":false,\"txt\":\"existing two\"}]", rootAction.formData.get("list")); } - + private void gotoAndSubmitConfig(final String viewName) throws Exception { HtmlPage p = j.createWebClient().goTo("self/" + viewName); HtmlForm f = p.getFormByName("config"); diff --git a/test/src/test/java/lib/form/TextAreaTest.java b/test/src/test/java/lib/form/TextAreaTest.java index 98c66c1e54be..e7285bc1416c 100644 --- a/test/src/test/java/lib/form/TextAreaTest.java +++ b/test/src/test/java/lib/form/TextAreaTest.java @@ -49,7 +49,7 @@ public String getText2() { @TestExtension public static class DescriptorImpl extends BuildStepDescriptor { - + String text1, text2; @Override diff --git a/test/src/test/java/lib/form/ValidateButtonTest.java b/test/src/test/java/lib/form/ValidateButtonTest.java index 92f77e2039b3..5f7433c7ce18 100644 --- a/test/src/test/java/lib/form/ValidateButtonTest.java +++ b/test/src/test/java/lib/form/ValidateButtonTest.java @@ -70,42 +70,42 @@ public class ValidateButtonTest { public void testValidateIsCalled() throws Exception { TestValidateIsCalled.DescriptorImpl d = j.jenkins.getDescriptorByType(TestValidateIsCalled.DescriptorImpl.class); assertNotNull(d); - + d.test1Outcome = new Exception(); // if doValidateTest1() doesn't get invoked, we want to know. HtmlPage p = j.createWebClient().goTo("test"); HtmlButton button = HtmlFormUtil.getButtonByCaption(p.getFormByName("config"), "test"); HtmlElementUtil.click(button); - + if (d.test1Outcome!=null) throw d.test1Outcome; } - + @TestExtension("testValidateIsCalled") public static final class TestValidateIsCalled implements Describable, UnprotectedRootAction { @Override public @CheckForNull String getIconFileName() { return null; } - + @Override public @CheckForNull String getDisplayName() { return null; } - + @Override public String getUrlName() { return "test"; } - + @Override public DescriptorImpl getDescriptor() { return Jenkins.get().getDescriptorByType(DescriptorImpl.class); } - + @Extension public static final class DescriptorImpl extends Descriptor { private Exception test1Outcome; - + public void doValidateTest1(@QueryParameter("a") String a, @QueryParameter("b") boolean b, @QueryParameter("c") boolean c, @QueryParameter("d") String d, @QueryParameter("e") String e) { @@ -122,94 +122,94 @@ public void doValidateTest1(@QueryParameter("a") String a, @QueryParameter("b") } } } - + @Test public void noInjectionArePossible() throws Exception { NoInjectionArePossible.DescriptorImpl d = j.jenkins.getDescriptorByType(NoInjectionArePossible.DescriptorImpl.class); assertNotNull(d); - + checkRegularCase(d); checkInjectionInMethod(d); checkInjectionInWith(d); } - + private void checkRegularCase(NoInjectionArePossible.DescriptorImpl descriptor) throws Exception { descriptor.paramMethod = "validateInjection"; descriptor.paramWith = "a,b"; - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); HtmlPage p = wc.goTo("test"); - + descriptor.wasCalled = false; HtmlElementUtil.click(getValidateButton(p)); assertNotEquals("hacked", p.getTitleText()); assertTrue(descriptor.wasCalled); } - + private void checkInjectionInMethod(NoInjectionArePossible.DescriptorImpl descriptor) throws Exception { descriptor.paramMethod = "validateInjection',document.title='hacked'+'"; descriptor.paramWith = "a,b"; - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); HtmlPage p = wc.goTo("test"); - + // no check on wasCalled because the button that is expected by the method is not passed (arguments are shifted due to the injection) HtmlElementUtil.click(getValidateButton(p)); assertNotEquals("hacked", p.getTitleText()); } - - + + private void checkInjectionInWith(NoInjectionArePossible.DescriptorImpl descriptor) throws Exception { descriptor.paramMethod = "validateInjection"; descriptor.paramWith = "a,b',document.title='hacked'+'"; - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); HtmlPage p = wc.goTo("test"); - + descriptor.wasCalled = false; HtmlElementUtil.click(getValidateButton(p)); assertNotEquals("hacked", p.getTitleText()); assertTrue(descriptor.wasCalled); } - + private HtmlButton getValidateButton(HtmlPage page){ DomNodeList buttons = page.getElementById("test-panel").getElementsByTagName("button"); assertEquals(1, buttons.size()); return (HtmlButton) buttons.get(0); } - + @TestExtension("noInjectionArePossible") public static final class NoInjectionArePossible implements Describable, UnprotectedRootAction { @Override public @CheckForNull String getIconFileName() { return null; } - + @Override public @CheckForNull String getDisplayName() { return null; } - + @Override public String getUrlName() { return "test"; } - + @Override public DescriptorImpl getDescriptor() { return Jenkins.get().getDescriptorByType(DescriptorImpl.class); } - + @Extension public static final class DescriptorImpl extends Descriptor { private boolean wasCalled = false; - + public String paramMethod = "validateInjection"; public String paramWith = null; - + public void doValidateInjection(StaplerRequest request) { wasCalled = true; } diff --git a/test/src/test/java/lib/layout/ConfirmationLinkTest.java b/test/src/test/java/lib/layout/ConfirmationLinkTest.java index 1390656d7d6c..ffa84af47cc4 100644 --- a/test/src/test/java/lib/layout/ConfirmationLinkTest.java +++ b/test/src/test/java/lib/layout/ConfirmationLinkTest.java @@ -49,11 +49,11 @@ public class ConfirmationLinkTest { @Rule public JenkinsRule j = new JenkinsRule(); - + private static final String hrefPayload = "',document.title='hacked'+'"; private static final String messagePayload = "',document.title='hacked'+'"; private static final String postPayload = "document.title='hacked'"; - + @Test public void noInjectionArePossible() throws Exception { TestRootAction testParams = j.jenkins.getExtensionList(UnprotectedRootAction.class).get(TestRootAction.class); @@ -65,135 +65,135 @@ public void noInjectionArePossible() throws Exception { checkInjectionInMessage(testParams); checkInjectionInPost(testParams); } - + private void checkRegularCase(TestRootAction testParams) throws Exception { testParams.paramHref = "#"; testParams.paramMessage = "Message to confirm the click"; testParams.paramClass = null; testParams.paramPost = null; - + HtmlPage p = j.createWebClient().goTo("test"); assertTrue(p.getWebResponse().getContentAsString().contains("Message to confirm the click")); } - + private void checkRegularCasePost(TestRootAction testParams) throws Exception { testParams.paramHref = "submit"; testParams.paramMessage = "Message to confirm the click"; testParams.paramClass = null; - + testParams.paramPost = true; assertMethodPostAfterClick(); - + testParams.paramPost = "true"; assertMethodPostAfterClick(); - + testParams.paramPost = false; assertMethodGetAfterClick(); - + testParams.paramPost = "false"; assertMethodGetAfterClick(); - + testParams.paramPost = "any other string"; assertMethodGetAfterClick(); } - + private void assertMethodGetAfterClick() throws Exception { Page pageAfterClick = getPageAfterClick(); assertTrue(pageAfterClick.getWebResponse().getContentAsString().contains("method:GET")); } - + private void assertMethodPostAfterClick() throws Exception { Page pageAfterClick = getPageAfterClick(); assertTrue(pageAfterClick.getWebResponse().getContentAsString().contains("method:POST")); } - + private Page getPageAfterClick() throws Exception { JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); HtmlPage p = wc.goTo("test"); - + return HtmlElementUtil.click(getClickableLink(p)); } - + private void checkInjectionInHref(TestRootAction testParams) throws Exception { testParams.paramHref = hrefPayload; testParams.paramMessage = "Message to confirm the click"; testParams.paramClass = null; testParams.paramPost = null; - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); HtmlPage p = wc.goTo("test"); - + Page pageAfterClick = HtmlElementUtil.click(getClickableLink(p)); assertNotEquals("hacked", p.getTitleText()); assertTrue(p.getWebResponse().getContentAsString().contains("Message to confirm the click")); // the url it clicks on is escaped and so does not exist assertEquals(HttpURLConnection.HTTP_NOT_FOUND, pageAfterClick.getWebResponse().getStatusCode()); } - + private void checkInjectionInMessage(TestRootAction testParams) throws Exception { testParams.paramHref = "#"; testParams.paramMessage = messagePayload; testParams.paramClass = null; testParams.paramPost = null; - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); HtmlPage p = wc.goTo("test"); - + Page pageAfterClick = HtmlElementUtil.click(getClickableLink(p)); assertNotEquals("hacked", p.getTitleText()); // the url is normally the same page so it's ok assertEquals(HttpURLConnection.HTTP_OK, pageAfterClick.getWebResponse().getStatusCode()); } - + private void checkInjectionInPost(TestRootAction testParams) throws Exception { testParams.paramHref = "#"; testParams.paramMessage = "Message to confirm the click"; testParams.paramClass = null; testParams.paramPost = postPayload; - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); HtmlPage p = wc.goTo("test"); - + Page pageAfterClick = HtmlElementUtil.click(getClickableLink(p)); assertNotEquals("hacked", p.getTitleText()); assertTrue(p.getWebResponse().getContentAsString().contains("Message to confirm the click")); // the url is normally the same page so it's ok assertEquals(HttpURLConnection.HTTP_OK, pageAfterClick.getWebResponse().getStatusCode()); } - + private HtmlAnchor getClickableLink(HtmlPage page){ DomNodeList anchors = page.getElementById("test-panel").getElementsByTagName("a"); assertEquals(1, anchors.size()); return (HtmlAnchor) anchors.get(0); } - + @TestExtension("noInjectionArePossible") public static final class TestRootAction implements UnprotectedRootAction { - + public String paramHref = ""; public String paramMessage = ""; public String paramClass; public Object paramPost; - + @Override public @CheckForNull String getIconFileName() { return null; } - + @Override public @CheckForNull String getDisplayName() { return null; } - + @Override public String getUrlName() { return "test"; } - + @WebMethod(name = "submit") public HttpResponse doSubmit(StaplerRequest request) { return HttpResponses.plainText("method:" + request.getMethod()); diff --git a/test/src/test/java/lib/layout/StopButtonTest.java b/test/src/test/java/lib/layout/StopButtonTest.java index 4a5ece5a6c97..205188f7acda 100644 --- a/test/src/test/java/lib/layout/StopButtonTest.java +++ b/test/src/test/java/lib/layout/StopButtonTest.java @@ -47,10 +47,10 @@ public class StopButtonTest { @Rule public JenkinsRule j = new JenkinsRule(); - + private static final String hrefPayload = "\",document.title='hacked',\""; private static final String postPayload = "\",document.title='hacked',\""; - + @Test public void noInjectionArePossible() throws Exception { TestRootAction testParams = j.jenkins.getExtensionList(UnprotectedRootAction.class).get(TestRootAction.class); @@ -61,86 +61,86 @@ public void noInjectionArePossible() throws Exception { checkInjectionInHrefWithConfirm(testParams); checkInjectionInConfirm(testParams); } - + private void checkRegularCase(TestRootAction testParams) throws Exception { testParams.paramHref = "#"; testParams.paramAlt = "Message to confirm the click"; testParams.paramConfirm = null; - + HtmlPage p = j.createWebClient().goTo("test"); assertTrue(p.getWebResponse().getContentAsString().contains("Message to confirm the click")); } - + private void checkInjectionInHref(TestRootAction testParams) throws Exception { testParams.paramHref = hrefPayload; testParams.paramAlt = "Alternative text for icon"; testParams.paramConfirm = null; - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); HtmlPage p = wc.goTo("test"); - + HtmlElementUtil.click(getStopLink(p)); assertNotEquals("hacked", p.getTitleText()); assertTrue(p.getWebResponse().getContentAsString().contains("Alternative text for icon")); } - + private void checkInjectionInHrefWithConfirm(TestRootAction testParams) throws Exception { testParams.paramHref = hrefPayload; testParams.paramAlt = "Alternative text for icon"; testParams.paramConfirm = "Confirm message"; - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); HtmlPage p = wc.goTo("test"); - + HtmlElementUtil.click(getStopLink(p)); assertNotEquals("hacked", p.getTitleText()); assertTrue(p.getWebResponse().getContentAsString().contains("Alternative text for icon")); } - + private void checkInjectionInConfirm(TestRootAction testParams) throws Exception { testParams.paramHref = "#"; testParams.paramAlt = "Alternative text for icon"; testParams.paramConfirm = postPayload; - + JenkinsRule.WebClient wc = j.createWebClient() .withThrowExceptionOnFailingStatusCode(false); HtmlPage p = wc.goTo("test"); - + HtmlElementUtil.click(getStopLink(p)); assertNotEquals("hacked", p.getTitleText()); assertTrue(p.getWebResponse().getContentAsString().contains("Alternative text for icon")); } - + private HtmlAnchor getStopLink(HtmlPage page){ DomNodeList anchors = page.getElementById("test-panel").getElementsByTagName("a"); assertEquals(1, anchors.size()); return (HtmlAnchor) anchors.get(0); } - + @TestExtension("noInjectionArePossible") public static class TestRootAction implements UnprotectedRootAction { - + public String paramHref = ""; public String paramAlt = ""; public String paramConfirm; - + @Override public @CheckForNull String getIconFileName() { return null; } - + @Override public @CheckForNull String getDisplayName() { return null; } - + @Override public @CheckForNull String getUrlName() { return "test"; } - + @WebMethod(name = "submit") public HttpResponse doSubmit(StaplerRequest request) { return HttpResponses.plainText("method:" + request.getMethod()); diff --git a/test/src/test/java/lib/layout/SvgIconTest.java b/test/src/test/java/lib/layout/SvgIconTest.java index c795d62f5e8e..bc490eff7325 100644 --- a/test/src/test/java/lib/layout/SvgIconTest.java +++ b/test/src/test/java/lib/layout/SvgIconTest.java @@ -57,7 +57,7 @@ public void regularUsage() throws Exception { HtmlPage p = j.createWebClient().goTo(testRootAction.getUrlName()); assertThat(p.getWebResponse().getContentAsString(), containsString(desiredTooltip)); } - + @Test @Issue("JENKINS-60920") public void onlyQuotesAreEscaped() throws Exception { @@ -76,7 +76,7 @@ public void onlyQuotesAreEscaped() throws Exception { not(containsString(pristineTooltip)) )); } - + @Test @Issue("SECURITY-1955") public void preventXssFromTooltip() throws Exception { @@ -106,7 +106,7 @@ private void ensureXssIsPrevented(TestRootAction testRootAction, String validati assertThat(jsControlResult, instanceOf(String.class)); String jsControlString = (String) jsControlResult; assertThat("The title attribute is not populated", jsControlString, containsString(validationPart)); - + page.executeJavaScript("document.querySelector('#test-panel svg').dispatchEvent(new Event('mouseover'));"); wc.waitForBackgroundJavaScript(1000); ScriptResult result = page.executeJavaScript("document.querySelector('#tt').innerHTML;"); diff --git a/war/pom.xml b/war/pom.xml index 007ba960d132..e71473d30ca0 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -40,9 +40,12 @@ THE SOFTWARE. ${basedir}/work - /jenkins - localhost - 8080 + + /jenkins + + localhost + + 8080 14.16.0 1.22.10 @@ -80,8 +83,8 @@ THE SOFTWARE. - metainf-services org.kohsuke.metainf-services + metainf-services com.google.code.findbugs @@ -195,10 +198,10 @@ THE SOFTWARE. list-dependencies - generate-resources list + generate-resources ${project.build.outputDirectory}/dependencies.txt @@ -206,10 +209,10 @@ THE SOFTWARE. executable-war-header - generate-resources unpack-dependencies + generate-resources org.jenkins-ci executable-war @@ -220,10 +223,10 @@ THE SOFTWARE. resgen - generate-resources copy + generate-resources @@ -243,10 +246,10 @@ THE SOFTWARE. detached-plugins - generate-resources copy + generate-resources + + support-log-formatter - generate-resources copy + generate-resources @@ -395,7 +399,8 @@ THE SOFTWARE. - + + com.cloudbees maven-license-plugin @@ -403,15 +408,13 @@ THE SOFTWARE. ${project.build.outputDirectory}/META-INF/licenses.xml ${project.build.outputDirectory}/META-INF/licenses.html true - - filter { + filter { // add Winstone since we are bundling it. def d = project.dependencies.find { it.artifactId=="winstone" }; def a = mojo.artifactFactory.createProjectArtifact(d.groupId,d.artifactId,d.version); def p = mojo.projectBuilder.buildFromRepository(a, project.getRemoteArtifactRepositories(), mojo.localRepository) models.put(a,p); - } - + } @@ -461,16 +464,13 @@ THE SOFTWARE. stapler.resourcePath - - ../core/src/main/resources; - + ../core/src/main/resources; hudson.bundled.plugins - - ${project.build.directory}/${project.build.finalName}/WEB-INF/plugins/*.hpi - + + ${project.build.directory}/${project.build.finalName}/WEB-INF/plugins/*.hpi @@ -487,7 +487,8 @@ THE SOFTWARE. ${project.basedir}/../core/src/main/resources,${project.basedir}/../core/target/classes,${project.build.directory}/support-log-formatter.jar ${contextPath} false - NONE + + NONE @@ -505,10 +506,10 @@ THE SOFTWARE. signWar - pre-integration-test sign + pre-integration-test ${project.build.directory}/${project.build.finalName}.war @@ -523,7 +524,6 @@ THE SOFTWARE. - @@ -595,22 +595,22 @@ THE SOFTWARE. - generate-sources yarn build yarn + generate-sources build - test yarn test yarn + test test ${skipTests} @@ -618,11 +618,11 @@ THE SOFTWARE. - test yarn lint yarn + test lint ${skipTests} @@ -637,12 +637,12 @@ THE SOFTWARE. clean-node - - package.json - cleanNode + + package.json +