.classpath
@@ -38,6 +38,18 @@ <classpathentry kind="lib" path="ext/xz-1.0.jar" sourcepath="ext/src/xz-1.0-sources.jar" /> <classpathentry kind="lib" path="ext/junit-4.10.jar" sourcepath="ext/src/junit-4.10-sources.jar" /> <classpathentry kind="lib" path="ext/hamcrest-core-1.1.jar" /> <classpathentry kind="lib" path="ext/seleniumhq/selenium-java-2.28.0.jar"/> <classpathentry kind="lib" path="ext/seleniumhq/selenium-api-2.28.0.jar"/> <classpathentry kind="lib" path="ext/seleniumhq/selenium-remote-driver-2.28.0.jar"/> <classpathentry kind="lib" path="ext/seleniumhq/selenium-support-2.28.0.jar"/> <classpathentry kind="lib" path="ext/seleniumhq/guava-12.0.jar"/> <classpathentry kind="lib" path="ext/seleniumhq/json-20080701.jar"/> <classpathentry kind="lib" path="ext/seleniumhq/commons-exec-1.1.jar"/> <classpathentry kind="lib" path="ext/seleniumhq/httpcore-4.2.1.jar"/> <classpathentry kind="lib" path="ext/seleniumhq/httpmime-4.2.1.jar"/> <classpathentry kind="lib" path="ext/seleniumhq/httpclient-4.2.1.jar"/> <classpathentry kind="lib" path="ext/seleniumhq/commons-logging-1.1.1.jar"/> <classpathentry kind="lib" path="ext/seleniumhq/selenium-firefox-driver-2.28.0.jar"/> <classpathentry kind="output" path="bin/classes" /> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER" /> </classpath> src/com/gitblit/build/Build.java
@@ -109,6 +109,20 @@ downloadFromApache(MavenObject.COMMONS_COMPRESS, BuildType.RUNTIME); downloadFromApache(MavenObject.XZ, BuildType.RUNTIME); //needed for selenium ui tests downloadFromApacheToExtSelenium(MavenObject.SEL_API, BuildType.RUNTIME); downloadFromApacheToExtSelenium(MavenObject.SEL_FF, BuildType.RUNTIME); downloadFromApacheToExtSelenium(MavenObject.SEL_JAVA, BuildType.RUNTIME); downloadFromApacheToExtSelenium(MavenObject.SEL_REMOTE, BuildType.RUNTIME); downloadFromApacheToExtSelenium(MavenObject.SEL_SUPPORT, BuildType.RUNTIME); downloadFromApacheToExtSelenium(MavenObject.GUAVA, BuildType.RUNTIME); downloadFromApacheToExtSelenium(MavenObject.JSON, BuildType.RUNTIME); downloadFromApacheToExtSelenium(MavenObject.COMMONS_EXEC, BuildType.RUNTIME); downloadFromApacheToExtSelenium(MavenObject.HTTPCLIENT, BuildType.RUNTIME); downloadFromApacheToExtSelenium(MavenObject.HTTPCORE, BuildType.RUNTIME); downloadFromApacheToExtSelenium(MavenObject.HTTPMIME, BuildType.RUNTIME); downloadFromApacheToExtSelenium(MavenObject.COMMONS_LOGGING, BuildType.RUNTIME); downloadFromEclipse(MavenObject.JGIT, BuildType.RUNTIME); downloadFromEclipse(MavenObject.JGIT_HTTP, BuildType.RUNTIME); } @@ -147,6 +161,20 @@ downloadFromApache(MavenObject.JCALENDAR, BuildType.COMPILETIME); downloadFromApache(MavenObject.COMMONS_COMPRESS, BuildType.COMPILETIME); downloadFromApache(MavenObject.XZ, BuildType.COMPILETIME); //needed for selenium ui tests downloadFromApacheToExtSelenium(MavenObject.SEL_API, BuildType.COMPILETIME); downloadFromApacheToExtSelenium(MavenObject.SEL_FF, BuildType.COMPILETIME); downloadFromApacheToExtSelenium(MavenObject.SEL_JAVA, BuildType.COMPILETIME); downloadFromApacheToExtSelenium(MavenObject.SEL_REMOTE, BuildType.COMPILETIME); downloadFromApacheToExtSelenium(MavenObject.SEL_SUPPORT, BuildType.COMPILETIME); downloadFromApacheToExtSelenium(MavenObject.GUAVA, BuildType.COMPILETIME); downloadFromApacheToExtSelenium(MavenObject.JSON, BuildType.COMPILETIME); downloadFromApacheToExtSelenium(MavenObject.COMMONS_EXEC, BuildType.COMPILETIME); downloadFromApacheToExtSelenium(MavenObject.HTTPCLIENT, BuildType.COMPILETIME); downloadFromApacheToExtSelenium(MavenObject.HTTPCORE, BuildType.COMPILETIME); downloadFromApacheToExtSelenium(MavenObject.HTTPMIME, BuildType.COMPILETIME); downloadFromApacheToExtSelenium(MavenObject.COMMONS_LOGGING, BuildType.COMPILETIME); downloadFromEclipse(MavenObject.JGIT, BuildType.COMPILETIME); downloadFromEclipse(MavenObject.JGIT_HTTP, BuildType.COMPILETIME); @@ -217,7 +245,7 @@ Properties properties = new Properties(); FileInputStream is = null; try { is = new FileInputStream(new File("distrib", Constants.PROPERTIES_FILE)); is = new FileInputStream(Constants.PROPERTIES_FILE); properties.load(is); } catch (Throwable t) { t.printStackTrace(); @@ -398,7 +426,7 @@ * the maven object to download. * @return */ private static List<File> downloadFromMaven(String mavenRoot, MavenObject mo, BuildType type) { private static List<File> downloadFromMaven(String mavenRoot, MavenObject mo, BuildType type, String targetFolder) { List<File> downloads = new ArrayList<File>(); String[] jars = { "" }; if (BuildType.RUNTIME.equals(type)) { @@ -407,9 +435,9 @@ jars = new String[] { "-sources" }; } for (String jar : jars) { File targetFile = mo.getLocalFile("ext", jar); File targetFile = mo.getLocalFile(targetFolder, jar); if ("-sources".equals(jar)) { File relocated = new File("ext/src", targetFile.getName()); File relocated = new File(targetFolder+"/src", targetFile.getName()); if (targetFile.exists()) { // move -sources jar to ext/src folder targetFile.renameTo(relocated); @@ -500,6 +528,31 @@ removeObsoleteArtifacts(mo, type, targetFile.getParentFile()); } return downloads; } /** * Download a file from the official Apache Maven repository. * * @param mo * the maven object to download. * @return */ private static List<File> downloadFromApacheToExtSelenium(MavenObject mo, BuildType type) { return downloadFromMaven("http://repo1.maven.org/maven2/", mo, type, "ext/seleniumhq"); } /** * Download a file from the official Apache Maven repository. * * @param mo * the maven object to download. * @return */ private static List<File> downloadFromMaven(String mavenRoot, MavenObject mo, BuildType type) { return downloadFromMaven(mavenRoot, mo, type, "ext"); } private static void removeObsoleteArtifacts(final MavenObject mo, final BuildType type, File folder) { @@ -796,6 +849,59 @@ "ecff5cb8b1189514c9d1d8d68eb77ac372e000c9", "f95e32a5d2dd8da643c4419814415b9704312993", ""); public static final MavenObject SEL_JAVA = new MavenObject( "selenium-java", "org/seleniumhq/selenium", "selenium-java", "2.28.0", 984098, 0, 0, "7606286989ac9cb942cc206d975ffe187c18d605", "4ede08d293dc153989a337cd0d31d26421433af5", ""); public static final MavenObject SEL_API = new MavenObject( "selenium-api", "org/seleniumhq/selenium", "selenium-api", "2.28.0", 984098, 0, 0, "c4044c40fff65cd25135a5f443638a2b1ccaeac5", "35fc6ec0804ae32b16a56627e69bdcb69995c515", ""); public static final MavenObject SEL_REMOTE = new MavenObject( "selenium-remote-driver", "org/seleniumhq/selenium", "selenium-remote-driver", "2.28.0", 984098, 0, 0, "c67f97cd94e02afec92b0ac881844febb4fc90be", "51a9c30de3c8c203cb7a474a10842443005a5fb4", ""); public static final MavenObject SEL_SUPPORT = new MavenObject( "selenium-support", "org/seleniumhq/selenium", "selenium-support", "2.28.0", 984098, 0, 0, "caf68d6310425f583bc592c08e43066b35eb94f6", "ce3831a601f5f50fda2f4604decde409b6c735a7", ""); public static final MavenObject SEL_FF = new MavenObject( "selenium-firefox-driver", "org/seleniumhq/selenium", "selenium-firefox-driver", "2.28.0", 984098, 0, 0, "a7c34e45dba39e65467b900aa67611aaa039692d", "aa8cd5fb49ca75a53d5b143406ea3d81ab3eddfd", ""); public static final MavenObject GUAVA = new MavenObject("guava", "com/google/guava", "guava", "12.0", 984098, 0, 0, "5bc66dd95b79db1e437eb08adba124a3e4088dc0", "f8b98e61865bed3c39b978ee3bf5c7fb990c4032", ""); public static final MavenObject JSON = new MavenObject("json", "org/json", "json", "20080701", 984098, 0, 0, "d652f102185530c93b66158b1859f35d45687258", "71bd54221e701df9d112bf9ba2918e13b0671f3a", ""); public static final MavenObject COMMONS_EXEC = new MavenObject( "commons-exec", "org/apache/commons", "commons-exec", "1.1", 984098, 0, 0, "07dfdf16fade726000564386825ed6d911a44ba1", "f60bea898e18b308099862e8634d589b06a8b0be", ""); public static final MavenObject HTTPCORE = new MavenObject("httpcore", "org/apache/httpcomponents", "httpcore", "4.2.1", 984098, 0, 0, "2d503272bf0a8b5f92d64db78b4ba9abbaccc6fd", "3f6caf5334fa83607b82e2f32dd128a9d8a0ea5e", ""); public static final MavenObject HTTPMIME = new MavenObject("httpmime", "org/apache/httpcomponents", "httpmime", "4.2.1", 984098, 0, 0, "7c772bace9aa31a728c39a88c6ff66a7cd177e89", "", "4e453843ae47f1c2d70e2eb2c13c037de4b614c4"); public static final MavenObject HTTPCLIENT = new MavenObject( "httpclient", "org/apache/httpcomponents", "httpclient", "4.2.1", 984098, 0, 0, "b69bd03af60bf487b3ae1209a644ecac587bf6fc", "6b27312b9c28b59aaeb6c21f3490045690c703d3", ""); public static final MavenObject COMMONS_LOGGING = new MavenObject( "commons-logging", "commons-logging", "commons-logging", "1.1.1", 984098, 0, 0, "5043bfebc3db072ed80fbd362e7caf00e885d8ae", "f3f156cbff0e0fb0d64bfce31a352cce4a33bc19", ""); public final String name; public final String group; public final String artifact; test-ui-gitblit.properties
New file @@ -0,0 +1,1203 @@ # # Git Servlet Settings # # Base folder for repositories. # This folder may contain bare and non-bare repositories but Gitblit will only # allow you to push to bare repositories. # Use forward slashes even on Windows!! # e.g. c:/gitrepos # # SINCE 0.5.0 # RESTART REQUIRED git.repositoriesFolder = ${baseFolder}/git # Build the available repository list at startup and cache this list for reuse. # This reduces disk io when presenting the repositories page, responding to rpcs, # etc, but it means that Gitblit will not automatically identify repositories # added or deleted by external tools. # # For this case you can use curl, wget, etc to issue an rpc request to clear the # cache (e.g. https://localhost/rpc?req=CLEAR_REPOSITORY_CACHE) # # SINCE 1.1.0 git.cacheRepositoryList = true # Search the repositories folder subfolders for other repositories. # Repositories MAY NOT be nested (i.e. one repository within another) # but they may be grouped together in subfolders. # e.g. c:/gitrepos/libraries/mylibrary.git # c:/gitrepos/libraries/myotherlibrary.git # # SINCE 0.5.0 git.searchRepositoriesSubfolders = true # Maximum number of folders to recurse into when searching for repositories. # The default value, -1, disables depth limits. # # SINCE 1.1.0 git.searchRecursionDepth = -1 # List of regex exclusion patterns to match against folders found in # *git.repositoriesFolder*. # Use forward slashes even on Windows!! # e.g. test/jgit\.git # # SPACE-DELIMITED # CASE-SENSITIVE # SINCE 1.1.0 git.searchExclusions = # List of regex url patterns for extracting a repository name when locating # submodules. # e.g. git.submoduleUrlPatterns = .*?://github.com/(.*) will extract # *gitblit/gitblit.git* from *git://github.com/gitblit/gitblit.git* # If no matches are found then the submodule repository name is assumed to be # whatever trails the last / character. (e.g. gitblit.git). # # SPACE-DELIMITED # CASE-SENSITIVE # SINCE 1.1.0 git.submoduleUrlPatterns = .*?://github.com/(.*) # Allow push/pull over http/https with JGit servlet. # If you do NOT want to allow Git clients to clone/push to Gitblit set this # to false. You might want to do this if you are only using ssh:// or git://. # If you set this false, consider changing the *web.otherUrls* setting to # indicate your clone/push urls. # # SINCE 0.5.0 git.enableGitServlet = true # If you want to restrict all git servlet access to those with valid X509 client # certificates then set this value to true. # # SINCE 1.2.0 git.requiresClientCertificate = false # Enforce date checks on client certificates to ensure that they are not being # used prematurely and that they have not expired. # # SINCE 1.2.0 git.enforceCertificateValidity = true # List of OIDs to extract from a client certificate DN to map a certificate to # an account username. # # e.g. git.certificateUsernameOIDs = CN # e.g. git.certificateUsernameOIDs = FirstName LastName # # SPACE-DELIMITED # SINCE 1.2.0 git.certificateUsernameOIDs = CN # Only serve/display bare repositories. # If there are non-bare repositories in git.repositoriesFolder and this setting # is true, they will be excluded from the ui. # # SINCE 0.9.0 git.onlyAccessBareRepositories = false # Allow an authenticated user to create a destination repository on a push if # the repository does not already exist. # # Administrator accounts can create a repository in any project. # These repositories are created with the default access restriction and authorization # control values. The pushing account is set as the owner. # # Non-administrator accounts with the CREATE role may create personal repositories. # These repositories are created as VIEW restricted for NAMED users. # The pushing account is set as the owner. # # SINCE 1.2.0 git.allowCreateOnPush = true # The default access restriction for new repositories. # Valid values are NONE, PUSH, CLONE, VIEW # NONE = anonymous view, clone, & push # PUSH = anonymous view & clone and authenticated push # CLONE = anonymous view, authenticated clone & push # VIEW = authenticated view, clone, & push # # SINCE 1.0.0 git.defaultAccessRestriction = NONE # The default authorization control for new repositories. # Valid values are AUTHENTICATED and NAMED # AUTHENTICATED = any authenticated user is granted restricted access # NAMED = only named users/teams are granted restricted access # # SINCE 1.1.0 git.defaultAuthorizationControl = NAMED # Enable JGit-based garbage collection. (!!EXPERIMENTAL!!) # # USE AT YOUR OWN RISK! # # If enabled, the garbage collection executor scans all repositories once a day # at the hour of your choosing. The GC executor will take each repository "offline", # one-at-a-time, to check if the repository satisfies it's GC trigger requirements. # # While the repository is offline it will be inaccessible from the web UI or from # any of the other services (git, rpc, rss, etc). # # Gitblit's GC Executor MAY NOT PLAY NICE with the other Git kids on the block, # especially on Windows systems, so if you are using other tools please coordinate # their usage with your GC Executor schedule or do not use this feature. # # The GC algorithm complex and the JGit team advises caution when using their # young implementation of GC. # # http://wiki.eclipse.org/EGit/New_and_Noteworthy/2.1#Garbage_Collector_and_Repository_Storage_Statistics # # EXPERIMENTAL # SINCE 1.2.0 # RESTART REQUIRED git.enableGarbageCollection = false # Hour of the day for the GC Executor to scan repositories. # This value is in 24-hour time. # # SINCE 1.2.0 git.garbageCollectionHour = 0 # The default minimum total filesize of loose objects to trigger early garbage # collection. # # You may specify a custom threshold for a repository in the repository's settings. # Common unit suffixes of k, m, or g are supported. # # SINCE 1.2.0 git.defaultGarbageCollectionThreshold = 500k # The default period, in days, between GCs for a repository. If the total filesize # of the loose object exceeds *git.garbageCollectionThreshold* or the repository's # custom threshold, this period will be short-circuited. # # e.g. if a repository collects 100KB of loose objects every day with a 500KB # threshold and a period of 7 days, it will take 5 days for the loose objects to # be collected, packed, and pruned. # # OR # # if a repository collects 10KB of loose objects every day with a 500KB threshold # and a period of 7 days, it will take the full 7 days for the loose objects to be # collected, packed, and pruned. # # You may specify a custom period for a repository in the repository's settings. # # The minimum value is 1 day since the GC Executor only runs once a day. # # SINCE 1.2.0 git.defaultGarbageCollectionPeriod = 7 # Number of bytes of a pack file to load into memory in a single read operation. # This is the "page size" of the JGit buffer cache, used for all pack access # operations. All disk IO occurs as single window reads. Setting this too large # may cause the process to load more data than is required; setting this too small # may increase the frequency of read() system calls. # # Default on JGit is 8 KiB on all platforms. # # Common unit suffixes of k, m, or g are supported. # Documentation courtesy of the Gerrit project. # # SINCE 1.0.0 # RESTART REQUIRED git.packedGitWindowSize = 8k # Maximum number of bytes to load and cache in memory from pack files. If JGit # needs to access more than this many bytes it will unload less frequently used # windows to reclaim memory space within the process. As this buffer must be shared # with the rest of the JVM heap, it should be a fraction of the total memory available. # # The JGit team recommends setting this value larger than the size of your biggest # repository. This ensures you can serve most requests from memory. # # Default on JGit is 10 MiB on all platforms. # # Common unit suffixes of k, m, or g are supported. # Documentation courtesy of the Gerrit project. # # SINCE 1.0.0 # RESTART REQUIRED git.packedGitLimit = 10m # Maximum number of bytes to reserve for caching base objects that multiple deltafied # objects reference. By storing the entire decompressed base object in a cache Git # is able to avoid unpacking and decompressing frequently used base objects multiple times. # # Default on JGit is 10 MiB on all platforms. You probably do not need to adjust # this value. # # Common unit suffixes of k, m, or g are supported. # Documentation courtesy of the Gerrit project. # # SINCE 1.0.0 # RESTART REQUIRED git.deltaBaseCacheLimit = 10m # Maximum number of pack files to have open at once. A pack file must be opened # in order for any of its data to be available in a cached window. # # If you increase this to a larger setting you may need to also adjust the ulimit # on file descriptors for the host JVM, as Gitblit needs additional file descriptors # available for network sockets and other repository data manipulation. # # Default on JGit is 128 file descriptors on all platforms. # Documentation courtesy of the Gerrit project. # # SINCE 1.0.0 # RESTART REQUIRED git.packedGitOpenFiles = 128 # Largest object size, in bytes, that JGit will allocate as a contiguous byte # array. Any file revision larger than this threshold will have to be streamed, # typically requiring the use of temporary files under $GIT_DIR/objects to implement # psuedo-random access during delta decompression. # # Servers with very high traffic should set this to be larger than the size of # their common big files. For example a server managing the Android platform # typically has to deal with ~10-12 MiB XML files, so 15 m would be a reasonable # setting in that environment. Setting this too high may cause the JVM to run out # of heap space when handling very big binary files, such as device firmware or # CD-ROM ISO images. Make sure to adjust your JVM heap accordingly. # # Default is 50 MiB on all platforms. # # Common unit suffixes of k, m, or g are supported. # Documentation courtesy of the Gerrit project. # # SINCE 1.0.0 # RESTART REQUIRED git.streamFileThreshold = 50m # When true, JGit will use mmap() rather than malloc()+read() to load data from # pack files. The use of mmap can be problematic on some JVMs as the garbage # collector must deduce that a memory mapped segment is no longer in use before # a call to munmap() can be made by the JVM native code. # # In server applications (such as Gitblit) that need to access many pack files, # setting this to true risks artificially running out of virtual address space, # as the garbage collector cannot reclaim unused mapped spaces fast enough. # # Default on JGit is false. Although potentially slower, it yields much more # predictable behavior. # Documentation courtesy of the Gerrit project. # # SINCE 1.0.0 # RESTART REQUIRED git.packedGitMmap = false # # Groovy Integration # # Location of Groovy scripts to use for Pre and Post receive hooks. # Use forward slashes even on Windows!! # e.g. c:/groovy # # RESTART REQUIRED # SINCE 0.8.0 groovy.scriptsFolder = ${baseFolder}/groovy # Specify the directory Grape uses for downloading libraries. # http://groovy.codehaus.org/Grape # # RESTART REQUIRED # SINCE 1.0.0 groovy.grapeFolder = ${baseFolder}/groovy/grape # Scripts to execute on Pre-Receive. # # These scripts execute after an incoming push has been parsed and validated # but BEFORE the changes are applied to the repository. You might reject a # push in this script based on the repository and branch the push is attempting # to change. # # Script names are case-sensitive on case-sensitive file systems. You may omit # the traditional ".groovy" from this list if your file extension is ".groovy" # # NOTE: # These scripts are only executed when pushing to *Gitblit*, not to other Git # tooling you may be using. Also note that these scripts are shared between # repositories. These are NOT repository-specific scripts! Within the script # you may customize the control-flow for a specific repository by checking the # *repository* variable. # # SPACE-DELIMITED # CASE-SENSITIVE # SINCE 0.8.0 groovy.preReceiveScripts = # Scripts to execute on Post-Receive. # # These scripts execute AFTER an incoming push has been applied to a repository. # You might trigger a continuous-integration build here or send a notification. # # Script names are case-sensitive on case-sensitive file systems. You may omit # the traditional ".groovy" from this list if your file extension is ".groovy" # # NOTE: # These scripts are only executed when pushing to *Gitblit*, not to other Git # tooling you may be using. Also note that these scripts are shared between # repositories. These are NOT repository-specific scripts! Within the script # you may customize the control-flow for a specific repository by checking the # *repository* variable. # # SPACE-DELIMITED # CASE-SENSITIVE # SINCE 0.8.0 groovy.postReceiveScripts = # Repository custom fields for Groovy Hook mechanism # # List of key=label pairs of custom fields to prompt for in the Edit Repository # page. These keys are stored in the repository's git config file in the # section [gitblit "customFields"]. Key names are alphanumeric only. These # fields are intended to be used for the Groovy hook mechanism where a script # can adjust it's execution based on the custom fields stored in the repository # config. # # e.g. "commitMsgRegex=Commit Message Regular Expression" anotherProperty=Another # # SPACE-DELIMITED # SINCE 1.0.0 groovy.customFields = # # Authentication Settings # # Require authentication to see everything but the admin pages # # SINCE 0.5.0 # RESTART REQUIRED web.authenticateViewPages = false # Require admin authentication for the admin functions and pages # # SINCE 0.5.0 # RESTART REQUIRED web.authenticateAdminPages = true # Allow Gitblit to store a cookie in the user's browser for automatic # authentication. The cookie is generated by the user service. # # SINCE 0.5.0 web.allowCookieAuthentication = true # Config file for storing project metadata # # SINCE 1.2.0 web.projectsFile = ${baseFolder}/projects.conf # Either the full path to a user config file (users.conf) # OR the full path to a simple user properties file (users.properties) # OR a fully qualified class name that implements the IUserService interface. # # Alternative user services: # com.gitblit.LdapUserService # com.gitblit.RedmineUserService # # Any custom user service implementation must have a public default constructor. # # SINCE 0.5.0 # RESTART REQUIRED realm.userService = test-ui-users.conf # How to store passwords. # Valid values are plain, md5, or combined-md5. md5 is the hash of password. # combined-md5 is the hash of username.toLowerCase()+password. # Default is md5. # # SINCE 0.5.0 realm.passwordStorage = md5 # Minimum valid length for a plain text password. # Default value is 5. Absolute minimum is 4. # # SINCE 0.5.0 realm.minPasswordLength = 5 # # Gitblit Web Settings # # If blank Gitblit is displayed. # # SINCE 0.5.0 web.siteName = # If *web.authenticateAdminPages*=true, users with "admin" role can create # repositories, create users, and edit repository metadata. # # If *web.authenticateAdminPages*=false, any user can execute the aforementioned # functions. # # SINCE 0.5.0 web.allowAdministration = true # Allows rpc clients to list repositories and possibly manage or administer the # Gitblit server, if the authenticated account has administrator permissions. # See *web.enableRpcManagement* and *web.enableRpcAdministration*. # # SINCE 0.7.0 web.enableRpcServlet = true # Allows rpc clients to manage repositories and users of the Gitblit instance, # if the authenticated account has administrator permissions. # Requires *web.enableRpcServlet=true*. # # SINCE 0.7.0 web.enableRpcManagement = false # Allows rpc clients to control the server settings and monitor the health of this # this Gitblit instance, if the authenticated account has administrator permissions. # Requires *web.enableRpcServlet=true* and *web.enableRpcManagement*. # # SINCE 0.7.0 web.enableRpcAdministration = false # Full path to a configurable robots.txt file. With this file you can control # what parts of your Gitblit server respectable robots are allowed to traverse. # http://googlewebmastercentral.blogspot.com/2008/06/improving-on-robots-exclusion-protocol.html # # SINCE 1.0.0 web.robots.txt = # If true, the web ui layout will respond and adapt to the browser's dimensions. # if false, the web ui will use a 940px fixed-width layout. # http://twitter.github.com/bootstrap/scaffolding.html#responsive # # SINCE 1.0.0 web.useResponsiveLayout = true # Allow Gravatar images to be displayed in Gitblit pages. # # SINCE 0.8.0 web.allowGravatar = true # Allow dynamic zip downloads. # # SINCE 0.5.0 web.allowZipDownloads = true # If *web.allowZipDownloads=true* the following formats will be displayed for # download compressed archive links: # # zip = standard .zip # tar = standard tar format (preserves *nix permissions and symlinks) # gz = gz-compressed tar # xz = xz-compressed tar # bzip2 = bzip2-compressed tar # # SPACE-DELIMITED # SINCE 1.2.0 web.compressedDownloads = zip gz # Allow optional Lucene integration. Lucene indexing is an opt-in feature. # A repository may specify branches to index with Lucene instead of using Git # commit traversal. There are scenarios where you may want to completely disable # Lucene indexing despite a repository specifying indexed branches. One such # scenario is on a resource-constrained federated Gitblit mirror. # # SINCE 0.9.0 web.allowLuceneIndexing = false # Allows an authenticated user to create forks of a repository # # set this to false if you want to disable all fork controls on the web site # web.allowForking = true # Controls the length of shortened commit hash ids # # SINCE 1.2.0 web.shortCommitIdLength = 6 # Use Clippy (Flash solution) to provide a copy-to-clipboard button. # If false, a button with a more primitive JavaScript-based prompt box will # offer a 3-step (click, ctrl+c, enter) copy-to-clipboard alternative. # # SINCE 0.8.0 web.allowFlashCopyToClipboard = true # Default maximum number of commits that a repository may contribute to the # activity page, regardless of the selected duration. This setting may be valuable # for an extremely busy server. This value may also be configed per-repository # in Edit Repository. 0 disables this throttle. # # SINCE 1.2.0 web.maxActivityCommits = 0 # Default number of entries to include in RSS Syndication links # # SINCE 0.5.0 web.syndicationEntries = 25 # Show the size of each repository on the repositories page. # This requires recursive traversal of each repository folder. This may be # non-performant on some operating systems and/or filesystems. # # SINCE 0.5.2 web.showRepositorySizes = true # List of custom regex expressions that can be displayed in the Filters menu # of the Repositories and Activity pages. Keep them very simple because you # are likely to run into encoding issues if they are too complex. # # Use !!! to separate the filters # # SINCE 0.8.0 web.customFilters = # Show federation registrations (without token) and the current pull status # to non-administrator users. # # SINCE 0.6.0 web.showFederationRegistrations = false # This is the message displayed when *web.authenticateViewPages=true*. # This can point to a file with Markdown content. # Specifying "gitblit" uses the internal login message. # # SINCE 0.7.0 web.loginMessage = gitblit # This is the message displayed above the repositories table. # This can point to a file with Markdown content. # Specifying "gitblit" uses the internal welcome message. # # SINCE 0.5.0 web.repositoriesMessage = gitblit # Ordered list of charsets/encodings to use when trying to display a blob. # If empty, UTF-8 and ISO-8859-1 are used. The server's default charset # is always appended to the encoding list. If all encodings fail to cleanly # decode the blob content, UTF-8 will be used with the standard malformed # input/unmappable character replacement strings. # # SPACE-DELIMITED # SINCE 1.0.0 web.blobEncodings = UTF-8 ISO-8859-1 # Manually set the default timezone to be used by Gitblit for display in the # web ui. This value is independent of the JVM timezone. Specifying a blank # value will default to the JVM timezone. # e.g. America/New_York, US/Pacific, UTC, Europe/Berlin # # SINCE 0.9.0 # RESTART REQUIRED web.timezone = # Use the client timezone when formatting dates. # This uses AJAX to determine the browser's timezone and may require more # server overhead because a Wicket session is created. All Gitblit pages # attempt to be stateless, if possible. # # SINCE 0.5.0 # RESTART REQUIRED web.useClientTimezone = false # Time format # <http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html> # # SINCE 0.8.0 web.timeFormat = HH:mm # Short date format # <http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html> # # SINCE 0.5.0 web.datestampShortFormat = yyyy-MM-dd # Long date format # # SINCE 0.8.0 web.datestampLongFormat = EEEE, MMMM d, yyyy # Long timestamp format # <http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html> # # SINCE 0.5.0 web.datetimestampLongFormat = EEEE, MMMM d, yyyy HH:mm Z # Mount URL parameters # This setting controls if pretty or parameter URLs are used. # i.e. # if true: # http://localhost/commit/myrepo/abcdef # if false: # http://localhost/commit/?r=myrepo&h=abcdef # # SINCE 0.5.0 # RESTART REQUIRED web.mountParameters = true # Some servlet containers (e.g. Tomcat >= 6.0.10) disallow '/' (%2F) encoding # in URLs as a security precaution for proxies. This setting tells Gitblit # to preemptively replace '/' with '*' or '!' for url string parameters. # # <https://issues.apache.org/jira/browse/WICKET-1303> # <http://tomcat.apache.org/security-6.html#Fixed_in_Apache_Tomcat_6.0.10> # Add *-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true* to your # *CATALINA_OPTS* or to your JVM launch parameters # # SINCE 0.5.2 web.forwardSlashCharacter = / # Show other URLs on the summary page for accessing your git repositories # Use spaces to separate urls. {0} is the token for the repository name. # e.g. # web.otherUrls = ssh://localhost/git/{0} git://localhost/git/{0} # # SPACE-DELIMITED # SINCE 0.5.0 web.otherUrls = # Choose how to present the repositories list. # grouped = group nested/subfolder repositories together (no sorting) # flat = flat list of repositories (sorting allowed) # # SINCE 0.5.0 web.repositoryListType = grouped # If using a grouped repository list and there are repositories at the # root level of your repositories folder, you may specify the displayed # group name with this setting. This value is only used for web presentation. # # SINCE 0.5.0 web.repositoryRootGroupName = main # Display the repository swatch color next to the repository name link in the # repositories list. # # SINCE 0.8.0 web.repositoryListSwatches = true # Choose the diff presentation style: gitblt, gitweb, or plain # # SINCE 0.5.0 web.diffStyle = gitblit # Control if email addresses are shown in web ui # # SINCE 0.5.0 web.showEmailAddresses = true # Shows a combobox in the page links header with commit, committer, and author # search selection. Default search is commit. # # SINCE 0.5.0 web.showSearchTypeSelection = false # Generates a line graph of repository activity over time on the Summary page. # This uses the Google Charts API. # # SINCE 0.5.0 web.generateActivityGraph = true # The number of days to show on the activity page. # Value must exceed 0 else default of 14 is used # # SINCE 0.8.0 web.activityDuration = 14 # The number of commits to display on the summary page # Value must exceed 0 else default of 20 is used # # SINCE 0.5.0 web.summaryCommitCount = 16 # The number of tags/branches to display on the summary page. # -1 = all tags/branches # 0 = hide tags/branches # N = N tags/branches # # SINCE 0.5.0 web.summaryRefsCount = 5 # The number of items to show on a page before showing the first, prev, next # pagination links. A default if 50 is used for any invalid value. # # SINCE 0.5.0 web.itemsPerPage = 50 # Registered file extensions to ignore during Lucene indexing # # SPACE-DELIMITED # SINCE 0.9.0 web.luceneIgnoreExtensions = 7z arc arj bin bmp dll doc docx exe gif gz jar jpg lib lzh odg odf odt pdf ppt png so swf xcf xls xlsx zip # Registered extensions for google-code-prettify # # SPACE-DELIMITED # SINCE 0.5.0 web.prettyPrintExtensions = c cpp cs css frm groovy htm html java js php pl prefs properties py rb scala sh sql xml vb # Registered extensions for markdown transformation # # SPACE-DELIMITED # CASE-SENSITIVE # SINCE 0.5.0 web.markdownExtensions = md mkd markdown MD MKD # Image extensions # # SPACE-DELIMITED # SINCE 0.5.0 web.imageExtensions = bmp jpg gif png # Registered extensions for binary blobs # # SPACE-DELIMITED # SINCE 0.5.0 web.binaryExtensions = jar pdf tar.gz zip # Aggressive heap management will run the garbage collector on every generated # page. This slows down page generation a little but improves heap consumption. # # SINCE 0.5.0 web.aggressiveHeapManagement = false # Run the webapp in debug mode # # SINCE 0.5.0 # RESTART REQUIRED web.debugMode = false # Enable/disable global regex substitutions (i.e. shared across repositories) # # SINCE 0.5.0 regex.global = true # Example global regex substitutions # Use !!! to separate the search pattern and the replace pattern # searchpattern!!!replacepattern # SINCE 0.5.0 regex.global.bug = \\b(Bug:)(\\s*[#]?|-){0,1}(\\d+)\\b!!!<a href="http://somehost/bug/$3">Bug-Id: $3</a> # SINCE 0.5.0 regex.global.changeid = \\b(Change-Id:\\s*)([A-Za-z0-9]*)\\b!!!<a href="http://somehost/changeid/$2">Change-Id: $2</a> # Example per-repository regex substitutions overrides global # SINCE 0.5.0 regex.myrepository.bug = \\b(Bug:)(\\s*[#]?|-){0,1}(\\d+)\\b!!!<a href="http://elsewhere/bug/$3">Bug-Id: $3</a> # # Mail Settings # SINCE 0.6.0 # # Mail settings are used to notify administrators of received federation proposals # # ip or hostname of smtp server # # SINCE 0.6.0 mail.server = # port to use for smtp requests # # SINCE 0.6.0 mail.port = 25 # debug the mail executor # # SINCE 0.6.0 mail.debug = false # if your smtp server requires authentication, supply the credentials here # # SINCE 0.6.0 mail.username = # SINCE 0.6.0 mail.password = # from address for generated emails # # SINCE 0.6.0 mail.fromAddress = # List of email addresses for the Gitblit administrators # # SPACE-DELIMITED # SINCE 0.6.0 mail.adminAddresses = # List of email addresses for sending push email notifications. # # This key currently requires use of the sendemail.groovy hook script. # If you set sendemail.groovy in *groovy.postReceiveScripts* then email # notifications for all repositories (regardless of access restrictions!) # will be sent to these addresses. # # SPACE-DELIMITED # SINCE 0.8.0 mail.mailingLists = # # Federation Settings # SINCE 0.6.0 # # A Gitblit federation is a way to backup one Gitblit instance to another. # # *git.enableGitServlet* must be true to use this feature. # Your federation name is used for federation status acknowledgments. If it is # unset, and you elect to send a status acknowledgment, your Gitblit instance # will be identified by its hostname, if available, else your internal ip address. # The source Gitblit instance will also append your external IP address to your # identification to differentiate multiple pulling systems behind a single proxy. # # SINCE 0.6.0 federation.name = # Specify the passphrase of this Gitblit instance. # # An unspecified (empty) passphrase disables processing federation requests. # # This value can be anything you want: an integer, a sentence, an haiku, etc. # Keep the value simple, though, to avoid Java properties file encoding issues. # # Changing your passphrase will break any registrations you have established with other # Gitblit instances. # # CASE-SENSITIVE # SINCE 0.6.0 # RESTART REQUIRED *(only to enable or disable federation)* federation.passphrase = # Control whether or not this Gitblit instance can receive federation proposals # from another Gitblit instance. Registering a federated Gitblit is a manual # process. Proposals help to simplify that process by allowing a remote Gitblit # instance to send your Gitblit instance the federation pull data. # # SINCE 0.6.0 federation.allowProposals = false # The destination folder for cached federation proposals. # Use forward slashes even on Windows!! # # SINCE 0.6.0 federation.proposalsFolder = ${baseFolder}/proposals # The default pull frequency if frequency is unspecified on a registration # # SINCE 0.6.0 federation.defaultFrequency = 60 mins # Federation Sets are named groups of repositories. The Federation Sets are # available for selection in the repository settings page. You can assign a # repository to one or more sets and then distribute the token for the set. # This allows you to grant federation pull access to a subset of your available # repositories. Tokens for federation sets only grant repository pull access. # # SPACE-DELIMITED # CASE-SENSITIVE # SINCE 0.6.0 federation.sets = # Federation pull registrations # Registrations are read once, at startup. # # RESTART REQUIRED # # frequency: # The shortest frequency allowed is every 5 minutes # Decimal frequency values are cast to integers # Frequency values may be specified in mins, hours, or days # Values that can not be parsed or are unspecified default to *federation.defaultFrequency* # # folder: # if unspecified, the folder is *git.repositoriesFolder* # if specified, the folder is relative to *git.repositoriesFolder* # # bare: # if true, each repository will be created as a *bare* repository and will not # have a working directory. # # if false, each repository will be created as a normal repository suitable # for local work. # # mirror: # if true, each repository HEAD is reset to *origin/master* after each pull. # The repository will be flagged *isFrozen* after the initial clone. # # if false, each repository HEAD will point to the FETCH_HEAD of the initial # clone from the origin until pushed to or otherwise manipulated. # # mergeAccounts: # if true, remote accounts and their permissions are merged into your # users.properties file # # notifyOnError: # if true and the mail configuration is properly set, administrators will be # notified by email of pull failures # # include and exclude: # Space-delimited list of repositories to include or exclude from pull # may be * wildcard to include or exclude all # may use fuzzy match (e.g. org.eclipse.*) # # (Nearly) Perfect Mirror example # #federation.example1.url = https://go.gitblit.com #federation.example1.token = 6f3b8a24bf970f17289b234284c94f43eb42f0e4 #federation.example1.frequency = 120 mins #federation.example1.folder = #federation.example1.bare = true #federation.example1.mirror = true #federation.example1.mergeAccounts = true # # Advanced Realm Settings # # URL of the LDAP server. # To use encrypted transport, use either ldaps:// URL for SSL or ldap+tls:// to # send StartTLS command. # # SINCE 1.0.0 realm.ldap.server = ldap://localhost # Login username for LDAP searches. # If this value is unspecified, anonymous LDAP login will be used. # # e.g. mydomain\\username # # SINCE 1.0.0 realm.ldap.username = cn=Directory Manager # Login password for LDAP searches. # # SINCE 1.0.0 realm.ldap.password = password # The LdapUserService must be backed by another user service for standard user # and team management. # default: users.conf # # SINCE 1.0.0 # RESTART REQUIRED realm.ldap.backingUserService = test-ui-users.conf # Delegate team membership control to LDAP. # # If true, team user memberships will be specified by LDAP groups. This will # disable team selection in Edit User and user selection in Edit Team. # # If false, LDAP will only be used for authentication and Gitblit will maintain # team memberships with the *realm.ldap.backingUserService*. # # SINCE 1.0.0 realm.ldap.maintainTeams = false # Root node for all LDAP users # # This is the root node from which subtree user searches will begin. # If blank, Gitblit will search ALL nodes. # # SINCE 1.0.0 realm.ldap.accountBase = OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain # Filter criteria for LDAP users # # Query pattern to use when searching for a user account. This may be any valid # LDAP query expression, including the standard (&) and (|) operators. # # Variables may be injected via the ${variableName} syntax. # Recognized variables are: # ${username} - The text entered as the user name # # SINCE 1.0.0 realm.ldap.accountPattern = (&(objectClass=person)(sAMAccountName=${username})) # Root node for all LDAP groups to be used as Gitblit Teams # # This is the root node from which subtree team searches will begin. # If blank, Gitblit will search ALL nodes. # # SINCE 1.0.0 realm.ldap.groupBase = OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain # Filter criteria for LDAP groups # # Query pattern to use when searching for a team. This may be any valid # LDAP query expression, including the standard (&) and (|) operators. # # Variables may be injected via the ${variableName} syntax. # Recognized variables are: # ${username} - The text entered as the user name # ${dn} - The Distinguished Name of the user logged in # # All attributes from the LDAP User record are available. For example, if a user # has an attribute "fullName" set to "John", "(fn=${fullName})" will be # translated to "(fn=John)". # # SINCE 1.0.0 realm.ldap.groupMemberPattern = (&(objectClass=group)(member=${dn})) # LDAP users or groups that should be given administrator privileges. # # Teams are specified with a leading '@' character. Groups with spaces in the # name can be entered as "@team name". # # e.g. realm.ldap.admins = john @git_admins "@git admins" # # SPACE-DELIMITED # SINCE 1.0.0 realm.ldap.admins = @Git_Admins # Attribute(s) on the USER record that indicate their display (or full) name. # Leave blank for no mapping available in LDAP. # # This may be a single attribute, or a string of multiple attributes. Examples: # displayName - Uses the attribute 'displayName' on the user record # ${personalTitle}. ${givenName} ${surname} - Will concatenate the 3 # attributes together, with a '.' after personalTitle # # SINCE 1.0.0 realm.ldap.displayName = displayName # Attribute(s) on the USER record that indicate their email address. # Leave blank for no mapping available in LDAP. # # This may be a single attribute, or a string of multiple attributes. Examples: # email - Uses the attribute 'email' on the user record # ${givenName}.${surname}@gitblit.com -Will concatenate the 2 attributes # together with a '.' and '@' creating something like first.last@gitblit.com # # SINCE 1.0.0 realm.ldap.email = email # The RedmineUserService must be backed by another user service for standard user # and team management. # default: users.conf # # RESTART REQUIRED realm.redmine.backingUserService = test-ui-users.conf # URL of the Redmine. realm.redmine.url = http://example.com/redmine # # Server Settings # # The temporary folder to decompress the embedded gitblit webapp. # # SINCE 0.5.0 # RESTART REQUIRED server.tempFolder = ${baseFolder}/temp # Use Jetty NIO connectors. If false, Jetty Socket connectors will be used. # # SINCE 0.5.0 # RESTART REQUIRED server.useNio = true # Context path for the GO application. You might want to change the context # path if running Gitblit behind a proxy layer such as mod_proxy. # # SINCE 0.7.0 # RESTART REQUIRED server.contextPath = / # Standard http port to serve. <= 0 disables this connector. # On Unix/Linux systems, ports < 1024 require root permissions. # Recommended value: 80 or 8080 # # SINCE 0.5.0 # RESTART REQUIRED server.httpPort = 0 # Secure/SSL https port to serve. <= 0 disables this connector. # On Unix/Linux systems, ports < 1024 require root permissions. # Recommended value: 443 or 8443 # # SINCE 0.5.0 # RESTART REQUIRED server.httpsPort = 8443 # Port for serving an Apache JServ Protocol (AJP) 1.3 connector for integrating # Gitblit GO into an Apache HTTP server setup. <= 0 disables this connector. # Recommended value: 8009 # # SINCE 0.9.0 # RESTART REQUIRED server.ajpPort = 0 # Specify the interface for Jetty to bind the standard connector. # You may specify an ip or an empty value to bind to all interfaces. # Specifying localhost will result in Gitblit ONLY listening to requests to # localhost. # # SINCE 0.5.0 # RESTART REQUIRED server.httpBindInterface = localhost # Specify the interface for Jetty to bind the secure connector. # You may specify an ip or an empty value to bind to all interfaces. # Specifying localhost will result in Gitblit ONLY listening to requests to # localhost. # # SINCE 0.5.0 # RESTART REQUIRED server.httpsBindInterface = localhost # Specify the interface for Jetty to bind the AJP connector. # You may specify an ip or an empty value to bind to all interfaces. # Specifying localhost will result in Gitblit ONLY listening to requests to # localhost. # # SINCE 0.9.0 # RESTART REQUIRED server.ajpBindInterface = localhost # Alias of certificate to use for https/SSL serving. If blank the first # certificate found in the keystore will be used. # # SINCE 1.2.0 # RESTART REQUIRED server.certificateAlias = localhost # Password for SSL keystore. # Keystore password and certificate password must match. # This is provided for convenience, its probably more secure to set this value # using the --storePassword command line parameter. # # If you are using the official JRE or JDK from Oracle you may not have the # JCE Unlimited Strength Jurisdiction Policy files bundled with your JVM. Because # of this, your store/key password can not exceed 7 characters. If you require # longer passwords you may need to install the JCE Unlimited Strength Jurisdiction # Policy files from Oracle. # # http://www.oracle.com/technetwork/java/javase/downloads/index.html # # Gitblit and the Gitblit Certificate Authority will both indicate if Unlimited # Strength encryption is available. # # SINCE 0.5.0 # RESTART REQUIRED server.storePassword = gitblit # If serving over https (recommended) you might consider requiring clients to # authenticate with ssl certificates. If enabled, only https clients with the # a valid client certificate will be able to access Gitblit. # # If disabled, client certificate authentication is optional and will be tried # first before falling-back to form authentication or basic authentication. # # Requiring client certificates to access any of Gitblit may be too extreme, # consider this carefully. # # SINCE 1.2.0 # RESTART REQUIRED server.requireClientCertificates = false # Port for shutdown monitor to listen on. # # SINCE 0.5.0 # RESTART REQUIRED server.shutdownPort = 8081 test-ui-users.conf
New file @@ -0,0 +1,44 @@ [user "admin"] password = admin cookie = dd94709528bb1c83d08f3088d4043f4742891f4f role = "#admin" role = "#notfederated" [user "userthree"] password = StoredInLDAP cookie = d7d3894fc517612aa6c595555b6e1ab8e147e597 displayName = User Three emailAddress = userthree@gitblit.com role = "#admin" [user "userone"] password = StoredInLDAP cookie = c97cd38e50858cd0b389ec61b18fb9a89b4da54c displayName = User One emailAddress = User.One@gitblit.com role = "#admin" [user "usertwo"] password = StoredInLDAP cookie = 498ca9bd2841d39050fa45d1d737b9f9f767858d displayName = User Two emailAddress = usertwo@gitblit.com role = "#admin" [user "basic"] password = MD5:f17aaabc20bfe045075927934fed52d2 cookie = dd94709528bb1c83d08f3088d4043f4742891f4f role = "#fork" repository = RW:~repocreator/shb.git repository = V:test/gitective.git [user "repocreator"] password = MD5:b77e53bb561c47368d133b22e285f60b cookie = dd94709528bb1c83d08f3088d4043f4742891f4f role = "#create" [team "Git_Admins"] role = "#none" user = userone [team "Git_Users"] role = "#none" user = userone user = usertwo user = userthree [team "Git Admins"] role = "#none" user = usertwo tests/de/akquinet/devops/GitblitRunnable.java
New file @@ -0,0 +1,134 @@ /* * Copyright 2013 akquinet tech@spree GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.akquinet.devops; import java.net.InetAddress; import java.net.ServerSocket; import com.gitblit.GitBlitServer; import com.gitblit.tests.GitBlitSuite; /** * This is a runnable implementation, that is used to run a gitblit server in a * separate thread (e.g. alongside test cases) * * @author saheba * */ public class GitblitRunnable implements Runnable { private int httpPort, httpsPort, shutdownPort; private String userPropertiesPath, gitblitPropertiesPath; private boolean startFailed = false; /** * constructor with reduced set of start params * * @param httpPort * @param httpsPort * @param shutdownPort * @param gitblitPropertiesPath * @param userPropertiesPath */ public GitblitRunnable(int httpPort, int httpsPort, int shutdownPort, String gitblitPropertiesPath, String userPropertiesPath) { this.httpPort = httpPort; this.httpsPort = httpsPort; this.shutdownPort = shutdownPort; this.userPropertiesPath = userPropertiesPath; this.gitblitPropertiesPath = gitblitPropertiesPath; } /* * (non-Javadoc) * * @see java.lang.Runnable#run() */ public void run() { boolean portsFree = false; long lastRun = -1; while (!portsFree) { long current = System.currentTimeMillis(); if (lastRun == -1 || lastRun + 100 < current) { portsFree = areAllPortsFree(new int[] { httpPort, httpsPort, shutdownPort }, "127.0.0.1"); } lastRun = current; } try { GitBlitServer.main("--httpPort", "" + httpPort, "--httpsPort", "" + httpsPort, "--shutdownPort", "" + shutdownPort, "--repositoriesFolder", "\"" + GitBlitSuite.REPOSITORIES.getAbsolutePath() + "\"", "--userService", userPropertiesPath, "--settings", gitblitPropertiesPath); setStartFailed(false); } catch (Exception iex) { System.out.println("Gitblit server start failed"); setStartFailed(true); } } /** * Method used to ensure that all ports are free, if the runnable is used * JUnit test classes. Be aware that JUnit's setUpClass and tearDownClass * methods, which are executed before and after a test class (consisting of * several test cases), may be executed parallely if they are part of a test * suite consisting of several test classes. Therefore the run method of * this class calls areAllPortsFree to check port availability before * starting another gitblit instance. * * @param ports * @param inetAddress * @return */ public static boolean areAllPortsFree(int[] ports, String inetAddress) { System.out .println("\n" + System.currentTimeMillis() + " ----------------------------------- testing if all ports are free ..."); String blockedPorts = ""; for (int i = 0; i < ports.length; i++) { ServerSocket s; try { s = new ServerSocket(ports[i], 1, InetAddress.getByName(inetAddress)); s.close(); } catch (Exception e) { if (!blockedPorts.equals("")) { blockedPorts += ", "; } } } if (blockedPorts.equals("")) { System.out .println(" ----------------------------------- ... verified"); return true; } System.out.println(" ----------------------------------- ... " + blockedPorts + " are still blocked"); return false; } private void setStartFailed(boolean startFailed) { this.startFailed = startFailed; } public boolean isStartFailed() { return startFailed; } } tests/de/akquinet/devops/LaunchWithUITestConfig.java
New file @@ -0,0 +1,126 @@ /* * Copyright 2013 akquinet tech@spree GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.akquinet.devops; import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import junit.framework.Assert; import org.junit.Test; import com.gitblit.Constants; import com.gitblit.GitBlitServer; import com.gitblit.tests.GitBlitSuite; /** * This test checks if it is possible to run two server instances in the same * JVM sequentially * * @author saheba * */ public class LaunchWithUITestConfig { @Test public void testSequentialLaunchOfSeveralInstances() throws InterruptedException { // different ports than in testParallelLaunchOfSeveralInstances to // ensure that both test cases do not affect each others test results int httpPort = 9191, httpsPort = 9292, shutdownPort = 9393; String gitblitPropertiesPath = "test-ui-gitblit.properties", usersPropertiesPath = "test-ui-users.conf"; GitblitRunnable gitblitRunnable = new GitblitRunnable(httpPort, httpsPort, shutdownPort, gitblitPropertiesPath, usersPropertiesPath); Thread serverThread = new Thread(gitblitRunnable); serverThread.start(); Thread.sleep(2000); Assert.assertFalse(gitblitRunnable.isStartFailed()); LaunchWithUITestConfig.shutdownGitBlitServer(shutdownPort); Thread.sleep(5000); GitblitRunnable gitblitRunnable2 = new GitblitRunnable(httpPort, httpsPort, shutdownPort, gitblitPropertiesPath, usersPropertiesPath); Thread serverThread2 = new Thread(gitblitRunnable2); serverThread2.start(); Thread.sleep(2000); Assert.assertFalse(gitblitRunnable2.isStartFailed()); LaunchWithUITestConfig.shutdownGitBlitServer(shutdownPort); } @Test public void testParallelLaunchOfSeveralInstances() throws InterruptedException { // different ports than in testSequentialLaunchOfSeveralInstances to // ensure that both test cases do not affect each others test results int httpPort = 9797, httpsPort = 9898, shutdownPort = 9999; int httpPort2 = 9494, httpsPort2 = 9595, shutdownPort2 = 9696; String gitblitPropertiesPath = "test-ui-gitblit.properties", usersPropertiesPath = "test-ui-users.conf"; GitblitRunnable gitblitRunnable = new GitblitRunnable(httpPort, httpsPort, shutdownPort, gitblitPropertiesPath, usersPropertiesPath); Thread serverThread = new Thread(gitblitRunnable); serverThread.start(); Thread.sleep(2000); Assert.assertFalse(gitblitRunnable.isStartFailed()); GitblitRunnable gitblitRunnable2 = new GitblitRunnable(httpPort2, httpsPort2, shutdownPort2, gitblitPropertiesPath, usersPropertiesPath); Thread serverThread2 = new Thread(gitblitRunnable2); serverThread2.start(); Thread.sleep(2000); Assert.assertFalse(gitblitRunnable2.isStartFailed()); LaunchWithUITestConfig.shutdownGitBlitServer(shutdownPort); LaunchWithUITestConfig.shutdownGitBlitServer(shutdownPort2); } /** * main runs the tests without assert checks. You have to check the console * output manually. * * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { new LaunchWithUITestConfig().testSequentialLaunchOfSeveralInstances(); new LaunchWithUITestConfig().testParallelLaunchOfSeveralInstances(); } private static void shutdownGitBlitServer(int shutdownPort) { try { Socket s = new Socket(InetAddress.getByName("127.0.0.1"), shutdownPort); OutputStream out = s.getOutputStream(); System.out.println("Sending Shutdown Request to " + Constants.NAME); out.write("\r\n".getBytes()); out.flush(); s.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } tests/de/akquinet/devops/ManualUITestLaunch.java
New file @@ -0,0 +1,14 @@ package de.akquinet.devops; public class ManualUITestLaunch { public static void main(String[] args) { int httpPort = 8080, httpsPort = 8443, shutdownPort = 8081; String gitblitPropertiesPath = "test-ui-gitblit.properties", usersPropertiesPath = "test-ui-users.conf"; GitblitRunnable gitblitRunnable = new GitblitRunnable(httpPort, httpsPort, shutdownPort, gitblitPropertiesPath, usersPropertiesPath); Thread serverThread = new Thread(gitblitRunnable); serverThread.start(); } } tests/de/akquinet/devops/test/ui/TestUISuite.java
New file @@ -0,0 +1,33 @@ /* * Copyright 2013 akquinet tech@spree GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.akquinet.devops.test.ui; import org.junit.runner.RunWith; import org.junit.runners.Suite; import de.akquinet.devops.test.ui.cases.UI_MultiAdminSupportTest; /** * the test suite including all selenium-based ui-tests. * * @author saheba * */ @RunWith(Suite.class) @Suite.SuiteClasses({ UI_MultiAdminSupportTest.class }) public class TestUISuite { } tests/de/akquinet/devops/test/ui/cases/UI_MultiAdminSupportTest.java
New file @@ -0,0 +1,93 @@ /* * Copyright 2013 akquinet tech@spree GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.akquinet.devops.test.ui.cases; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import de.akquinet.devops.test.ui.generic.AbstractUITest; import de.akquinet.devops.test.ui.view.RepoEditView; import de.akquinet.devops.test.ui.view.RepoListView; /** * tests the multi admin per repo feature. * * @author saheba * */ public class UI_MultiAdminSupportTest extends AbstractUITest { String baseUrl = "https://localhost:8443"; RepoListView view; RepoEditView editView; private static final String TEST_MULTI_ADMIN_SUPPORT_REPO_NAME = "testmultiadminsupport"; private static final String TEST_MULTI_ADMIN_SUPPORT_REPO_PATH = "~repocreator/" + TEST_MULTI_ADMIN_SUPPORT_REPO_NAME + ".git"; private static final String TEST_MULTI_ADMIN_SUPPORT_REPO_PATH_WITHOUT_SUFFIX = "~repocreator/" + TEST_MULTI_ADMIN_SUPPORT_REPO_NAME; @Before public void before() { System.out.println("IN BEFORE"); this.view = new RepoListView(AbstractUITest.getDriver(), baseUrl); this.editView = new RepoEditView(AbstractUITest.getDriver()); AbstractUITest.getDriver().navigate().to(baseUrl); } @Test public void test_MultiAdminSelectionInStandardRepo() { // login view.login("repocreator", "repocreator"); // create new repo view.navigateToNewRepo(1); editView.changeName(TEST_MULTI_ADMIN_SUPPORT_REPO_PATH); Assert.assertTrue(editView.navigateToPermissionsTab()); Assert.assertTrue(editView .changeAccessRestriction(RepoEditView.RESTRICTION_AUTHENTICATED_VCP)); Assert.assertTrue(editView .changeAuthorizationControl(RepoEditView.AUTHCONTROL_RWALL)); // with a second admin editView.addRepoAdministrator("admin"); Assert.assertTrue(editView.save()); // user is automatically forwarded to repo list view Assert.assertTrue(view.isEmptyRepo(TEST_MULTI_ADMIN_SUPPORT_REPO_PATH)); Assert.assertTrue(view .isEditableRepo(TEST_MULTI_ADMIN_SUPPORT_REPO_PATH)); Assert.assertTrue(view .isDeletableRepo(TEST_MULTI_ADMIN_SUPPORT_REPO_PATH_WITHOUT_SUFFIX)); // logout repocreator view.logout(); // check with admin account if second admin has the same rights view.login("admin", "admin"); Assert.assertTrue(view.isEmptyRepo(TEST_MULTI_ADMIN_SUPPORT_REPO_PATH)); Assert.assertTrue(view .isEditableRepo(TEST_MULTI_ADMIN_SUPPORT_REPO_PATH)); Assert.assertTrue(view .isDeletableRepo(TEST_MULTI_ADMIN_SUPPORT_REPO_PATH_WITHOUT_SUFFIX)); // delete repo to reach state as before test execution view.navigateToDeleteRepo(TEST_MULTI_ADMIN_SUPPORT_REPO_PATH_WITHOUT_SUFFIX); view.acceptAlertDialog(); view.logout(); Assert.assertTrue(view.isLoginPartVisible()); } } tests/de/akquinet/devops/test/ui/generic/AbstractUITest.java
New file @@ -0,0 +1,96 @@ /* * Copyright 2013 akquinet tech@spree GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.akquinet.devops.test.ui.generic; import org.junit.AfterClass; import org.junit.BeforeClass; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxProfile; import com.gitblit.GitBlitServer; import de.akquinet.devops.GitblitRunnable; /** * This abstract class implements the setUpClass and tearDownClass for * selenium-based UITests. They require a running gitblit server instance and a * webdriver instance, which are managed by the setUpClass and tearDownClass * method. Write a separate test class derived from this abstract class for each * scenario consisting of one or more test cases, which can share the same * server instance. * * @author saheba * */ public abstract class AbstractUITest { private static Thread serverThread; private static WebDriver driver; private static final int HTTP_PORT = 8080, HTTPS_PORT = 8443, SHUTDOWN_PORT = 8081; private static final String GITBLIT_PROPERTIES_PATH = "test-ui-gitblit.properties", USERS_PROPERTIES_PATH = "test-ui-users.conf"; /** * starts a gitblit server instance in a separate thread before test cases * of concrete, non-abstract child-classes are executed */ @BeforeClass public static void setUpClass() { Runnable gitblitRunnable = new GitblitRunnable(HTTP_PORT, HTTPS_PORT, SHUTDOWN_PORT, GITBLIT_PROPERTIES_PATH, USERS_PROPERTIES_PATH); serverThread = new Thread(gitblitRunnable); serverThread.start(); FirefoxProfile firefoxProfile = new FirefoxProfile(); firefoxProfile.setPreference("startup.homepage_welcome_url", "https://www.google.de"); firefoxProfile.setPreference("browser.download.folderList", 2); firefoxProfile.setPreference( "browser.download.manager.showWhenStarting", false); String downloadDir = System.getProperty("java.io.tmpdir"); firefoxProfile.setPreference("browser.download.dir", downloadDir); firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk", "text/csv,text/plain,application/zip,application/pdf"); firefoxProfile.setPreference("browser.helperApps.alwaysAsk.force", false); System.out.println("Saving all attachments to: " + downloadDir); driver = new FirefoxDriver(firefoxProfile); } /** * stops the gitblit server instance running in a separate thread after test * cases of concrete, non-abstract child-classes have been executed */ @AfterClass public static void tearDownClass() throws InterruptedException { driver.close(); // Stop Gitblit GitBlitServer.main("--stop", "--shutdownPort", "" + SHUTDOWN_PORT); // Wait a few seconds for it to be running completely including thread // destruction Thread.sleep(1000); } public static WebDriver getDriver() { return AbstractUITest.driver; } } tests/de/akquinet/devops/test/ui/view/Exp.java
New file @@ -0,0 +1,45 @@ /* * Copyright 2013 akquinet tech@spree GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.akquinet.devops.test.ui.view; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedCondition; /** * container class for selenium conditions * * @author saheba * */ public class Exp { public static class EditRepoViewLoaded implements ExpectedCondition<Boolean> { public Boolean apply(WebDriver d) { List<WebElement> findElements = d.findElements(By.partialLinkText("general")); return findElements.size() == 1; } } public static class RepoListViewLoaded implements ExpectedCondition<Boolean> { public Boolean apply(WebDriver d) { String xpath = "//img[@src=\"git-black-16x16.png\"]"; List<WebElement> findElements = d.findElements(By.xpath(xpath )); return findElements.size() == 1; } } } tests/de/akquinet/devops/test/ui/view/GitblitDashboardView.java
New file @@ -0,0 +1,100 @@ /* * Copyright 2013 akquinet tech@spree GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.akquinet.devops.test.ui.view; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.WebDriverWait; /** * class representing the view componenents and possible user interactions, you * can see and do on most screens when you are logged in. * * @author saheba * */ public class GitblitDashboardView extends GitblitPageView { public static final String TITLE_STARTS_WITH = "localhost"; public GitblitDashboardView(WebDriver driver, String baseUrl) { super(driver, baseUrl); } public boolean isLoginPartVisible() { List<WebElement> found = getDriver().findElements( By.partialLinkText("logout")); return found == null || found.size() == 0; } public void logout() { // String pathLogout = "//a[@href =\"?" + WICKET_HREF_PAGE_PATH // + ".LogoutPage\"]"; // List<WebElement> logout = // getDriver().findElements(By.xpath(pathLogout)); // logout.get(0).click(); // replaced by url call because click hangs sometimes if the clicked // object is not a button or selenium ff driver does not notice the // change for any other reason getDriver().navigate().to( getBaseUrl() + "?" + WICKET_HREF_PAGE_PATH + ".LogoutPage"); } public static final String LOGIN_AREA_SELECTOR = "//span[@class = \"form-search\" ]"; public static final String WICKET_PAGES_PACKAGE_NAME = "com.gitblit.wicket.pages"; public static final String WICKET_HREF_PAGE_PATH = "wicket:bookmarkablePage=:" + WICKET_PAGES_PACKAGE_NAME; synchronized public void waitToLoadFor(int sec) { WebDriverWait webDriverWait = new WebDriverWait(getDriver(), sec); webDriverWait.until(new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver d) { return d.getTitle().toLowerCase() .startsWith(GitblitDashboardView.TITLE_STARTS_WITH); } }); } public void login(String id, String pw) { String pathID = LOGIN_AREA_SELECTOR + "/input[@name = \"username\" ]"; String pathPW = LOGIN_AREA_SELECTOR + "/input[@name = \"password\" ]"; String pathSubmit = LOGIN_AREA_SELECTOR + "/button[@type = \"submit\" ]"; // System.out.println("DRIVER:"+getDriver()); // List<WebElement> findElement = // getDriver().findElements(By.xpath("//span[@class = \"form-search\" ]")); // // System.out.println("ELEM: "+findElement); // System.out.println("SIZE: "+findElement.size()); // System.out.println("XPath: "+pathID); WebElement idField = getDriver().findElement(By.xpath(pathID)); // System.out.println("IDFIELD:"+idField); idField.sendKeys(id); WebElement pwField = getDriver().findElement(By.xpath(pathPW)); // System.out.println(pwField); pwField.sendKeys(pw); WebElement submit = getDriver().findElement(By.xpath(pathSubmit)); submit.click(); } public void acceptAlertDialog() { getDriver().switchTo().alert().accept(); } } tests/de/akquinet/devops/test/ui/view/GitblitPageView.java
New file @@ -0,0 +1,73 @@ /* * Copyright 2013 akquinet tech@spree GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.akquinet.devops.test.ui.view; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; /** * general basic class representing a gitblit webpage and offering basic methods * used in selenium tests. * * @author saheba * */ public class GitblitPageView { private WebDriver driver; private String baseUrl; public GitblitPageView(WebDriver driver, String baseUrl) { this.driver = driver; this.baseUrl = baseUrl; } public void sleep(int miliseconds) { try { Thread.sleep(miliseconds); } catch (InterruptedException e) { e.printStackTrace(); } } public WebElement getElementWithFocus() { String elScript = "return document.activeElement;"; WebElement focuseedEl = (WebElement) ((JavascriptExecutor) getDriver()) .executeScript(elScript); return focuseedEl; } public void navigateToPreviousPageOfBrowserHistory() { driver.navigate().back(); } public void setDriver(WebDriver driver) { this.driver = driver; } public WebDriver getDriver() { return driver; } public void setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; } public String getBaseUrl() { return baseUrl; } } tests/de/akquinet/devops/test/ui/view/RepoEditView.java
New file @@ -0,0 +1,158 @@ /* * Copyright 2013 akquinet tech@spree GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.akquinet.devops.test.ui.view; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.WebDriverWait; /** * class representing the tabs you can access when you edit a repo. * * @author saheba * */ public class RepoEditView extends GitblitDashboardView { public static final String PERMISSION_VIEW_USERS_NAME_PREFIX = "users:"; public static final String PERMISSION_VIEW_TEAMS_NAME_PREFIX = "teams:"; public static final String PERMISSION_VIEW_MUTABLE = "permissionToggleForm:showMutable"; public static final String PERMISSION_VIEW_SPECIFIED = "permissionToggleForm:showSpecified"; public static final String PERMISSION_VIEW_EFFECTIVE = "permissionToggleForm:showEffective"; public static final int RESTRICTION_ANONYMOUS_VCP = 0; public static final int RESTRICTION_AUTHENTICATED_P = 1; public static final int RESTRICTION_AUTHENTICATED_CP = 2; public static final int RESTRICTION_AUTHENTICATED_VCP = 3; public static final int AUTHCONTROL_RWALL = 0; public static final int AUTHOCONTROL_FINE = 1; public RepoEditView(WebDriver driver) { super(driver, null); } public void changeName(String newName) { String pathName = "//input[@id = \"name\" ]"; WebElement field = getDriver().findElement(By.xpath(pathName)); field.clear(); field.sendKeys(newName); } public boolean navigateToPermissionsTab() { String linkText = "access permissions"; List<WebElement> found = getDriver().findElements( By.partialLinkText(linkText)); System.out.println("PERM TABS found =" + found.size()); if (found != null && found.size() == 1) { found.get(0).click(); return true; } return false; } private void changeRepoAdministrators(String action, String affectedSelection, String username) { String xpath = "//select[@name=\"" + affectedSelection + "\"]/option[@value = \"" + username + "\" ]"; WebElement option = getDriver().findElement(By.xpath(xpath)); option.click(); String buttonPath = "//button[@class=\"button " + action + "\"]"; WebElement button = getDriver().findElement(By.xpath(buttonPath)); button.click(); } public void removeRepoAdministrator(String username) { changeRepoAdministrators("remove", "repoAdministrators:selection", username); } public void addRepoAdministrator(String username) { changeRepoAdministrators("add", "repoAdministrators:choices", username); } public WebElement getAccessRestrictionSelection() { String xpath = "//select[@name =\"accessRestriction\"]"; List<WebElement> found = getDriver().findElements(By.xpath(xpath)); if (found != null && found.size() == 1) { return found.get(0); } return null; } public boolean changeAccessRestriction(int option) { WebElement accessRestrictionSelection = getAccessRestrictionSelection(); if (accessRestrictionSelection == null) { return false; } accessRestrictionSelection.click(); sleep(100); String xpath = "//select[@name =\"accessRestriction\"]/option[@value=\"" + option + "\"]"; List<WebElement> found = getDriver().findElements(By.xpath(xpath)); if (found == null || found.size() == 0 || found.size() > 1) { return false; } found.get(0).click(); return true; } public boolean changeAuthorizationControl(int option) { System.out.println("try to change auth control"); String xpath = "//input[@name =\"authorizationControl\" and @value=\"" + option + "\"]"; List<WebElement> found = getDriver().findElements(By.xpath(xpath)); System.out.println("found auth CONTROL options " + found.size()); if (found == null || found.size() == 0 || found.size() > 1) { return false; } found.get(0).click(); return true; } private boolean isPermissionViewDisabled(String prefix, String view) { String xpath = "//[@name =\"" + prefix + view + "\"]"; List<WebElement> found = getDriver().findElements(By.xpath(xpath)); if (found == null || found.size() == 0 || found.size() > 1) { return false; } String attrValue = found.get(0).getAttribute("disabled"); return (attrValue != null) && (attrValue.equals("disabled")); } public boolean isPermissionViewSectionDisabled(String prefix) { return isPermissionViewDisabled(prefix, PERMISSION_VIEW_MUTABLE) && isPermissionViewDisabled(prefix, PERMISSION_VIEW_SPECIFIED) && isPermissionViewDisabled(prefix, PERMISSION_VIEW_EFFECTIVE); } public boolean save() { String xpath = "//div[@class=\"form-actions\"]/input[@name =\"" + "save" + "\"]"; List<WebElement> found = getDriver().findElements(By.xpath(xpath)); if (found == null || found.size() == 0 || found.size() > 1) { return false; } found.get(0).click(); WebDriverWait webDriverWait = new WebDriverWait(getDriver(), 1); webDriverWait.until(new Exp.RepoListViewLoaded()); return true; } } tests/de/akquinet/devops/test/ui/view/RepoListView.java
New file @@ -0,0 +1,130 @@ /* * Copyright 2013 akquinet tech@spree GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.akquinet.devops.test.ui.view; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.WebDriverWait; /** * class representing the repo list view, which you see e.g. right after you * logged in. * * @author saheba * */ public class RepoListView extends GitblitDashboardView { public RepoListView(WebDriver driver, String baseUrl) { super(driver, baseUrl); } public boolean isEmptyRepo(String fullyQualifiedRepoName) { String pathToLink = "//a[@href = \"?" + WICKET_HREF_PAGE_PATH + ".EmptyRepositoryPage&r=" + fullyQualifiedRepoName + "\"]"; List<WebElement> found = getDriver().findElements(By.xpath(pathToLink)); return found != null && found.size() > 0; } private String getEditRepoPath(String fullyQualifiedRepoName) { return "//a[@href =\"?" + WICKET_HREF_PAGE_PATH + ".EditRepositoryPage&r=" + fullyQualifiedRepoName + "\"]"; } private String getDeleteRepoOnclickIdentifier( String fullyQualifiedRepoPathAndName) { return "var conf = confirm('Delete repository \"" + fullyQualifiedRepoPathAndName + "\"?'); if (!conf) return false; "; } public boolean navigateToNewRepo(long waitSecToLoad) { String pathToLink = "//a[@href =\"?" + WICKET_HREF_PAGE_PATH + ".EditRepositoryPage\"]"; List<WebElement> found = getDriver().findElements(By.xpath(pathToLink)); if (found == null || found.size() == 0 || found.size() > 1) { return false; } found.get(0).click(); WebDriverWait webDriverWait = new WebDriverWait(getDriver(), waitSecToLoad); webDriverWait.until(new Exp.EditRepoViewLoaded()); return true; } private boolean checkOrDoEditRepo(String fullyQualifiedRepoName, boolean doEdit) { List<WebElement> found = getDriver().findElements( By.xpath(getEditRepoPath(fullyQualifiedRepoName))); if (found == null || found.size() == 0 || found.size() > 1) { return false; } if (doEdit) { found.get(0).click(); } return true; } public boolean navigateToEditRepo(String fullyQualifiedRepoName, int waitSecToLoad) { boolean result = checkOrDoEditRepo(fullyQualifiedRepoName, true); WebDriverWait webDriverWait = new WebDriverWait(getDriver(), waitSecToLoad); webDriverWait.until(new Exp.EditRepoViewLoaded()); return result; } public boolean isEditableRepo(String fullyQualifiedRepoName) { return checkOrDoEditRepo(fullyQualifiedRepoName, false); } private boolean checkOrDoDeleteRepo(String fullyQualifiedRepoPathAndName, boolean doDelete) { List<WebElement> found = getDriver().findElements( By.partialLinkText("delete")); String onclickIdentifier = getDeleteRepoOnclickIdentifier(fullyQualifiedRepoPathAndName); WebElement result = null; for (WebElement webElement : found) { if (webElement.getAttribute("onclick") != null && webElement.getAttribute("onclick").equals( onclickIdentifier)) { result = webElement; break; } } System.out.println("result ? " + result); if (result == null) { return false; } if (doDelete) { System.out.println(".............. DO DELETE .... "); result.click(); } return true; } public boolean isDeletableRepo(String fullyQualifiedRepoPathAndName) { return checkOrDoDeleteRepo(fullyQualifiedRepoPathAndName, false); } public boolean navigateToDeleteRepo(String fullyQualifiedRepoPathAndName) { return checkOrDoDeleteRepo(fullyQualifiedRepoPathAndName, true); } }