Merge branch 'stable-3.0' into stable-3.1

* stable-3.0:
  ChangeEditModifier: Reject invalid file paths as '400 Bad Request'
  Remove orphan library downloader facility
  Fix a bug where _moreChanges is set to the wrong value
  Don't check conflicting ref names when deleting refs

Change-Id: Ic18373c4b4024de7bb9a50a8ac22651435e3b9cf
This commit is contained in:
David Pursehouse
2020-01-16 11:30:38 +09:00
10 changed files with 49 additions and 575 deletions

View File

@@ -150,6 +150,7 @@ public class RefUpdateUtil {
public static void deleteChecked(Repository repo, String refName) throws IOException {
RefUpdate ru = repo.updateRef(refName);
ru.setForceUpdate(true);
ru.setCheckConflicting(false);
switch (ru.delete()) {
case FORCED:
// Ref was deleted.

View File

@@ -34,8 +34,6 @@ public class InitModule extends FactoryModule {
@Override
protected void configure() {
bind(SitePaths.class);
bind(Libraries.class);
bind(LibraryDownloader.class);
factory(Section.Factory.class);
factory(VersionedAuthorizedKeysOnInit.Factory.class);

View File

@@ -1,141 +0,0 @@
// Copyright (C) 2009 The Android Open Source Project
//
// 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 com.google.gerrit.pgm.init;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.gerrit.pgm.init.api.LibraryDownload;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
/** Standard {@link LibraryDownloader} instances derived from configuration. */
@Singleton
class Libraries {
private static final String RESOURCE_FILE = "com/google/gerrit/pgm/init/libraries.config";
private final Provider<LibraryDownloader> downloadProvider;
private final List<String> skippedDownloads;
private final boolean skipAllDownloads;
/* final */ LibraryDownloader db2Driver;
/* final */ LibraryDownloader db2DriverLicense;
/* final */ LibraryDownloader hanaDriver;
/* final */ LibraryDownloader mariadbDriver;
/* final */ LibraryDownloader mysqlDriver;
/* final */ LibraryDownloader oracleDriver;
@Inject
Libraries(
final Provider<LibraryDownloader> downloadProvider,
@LibraryDownload List<String> skippedDownloads,
@LibraryDownload Boolean skipAllDownloads) {
this.downloadProvider = downloadProvider;
this.skippedDownloads = skippedDownloads;
this.skipAllDownloads = skipAllDownloads;
init();
}
private void init() {
final Config cfg = new Config();
try {
cfg.fromText(read(RESOURCE_FILE));
} catch (IOException | ConfigInvalidException e) {
throw new RuntimeException(e.getMessage(), e);
}
for (Field f : Libraries.class.getDeclaredFields()) {
if ((f.getModifiers() & Modifier.STATIC) == 0 && f.getType() == LibraryDownloader.class) {
try {
f.set(this, downloadProvider.get());
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException("Cannot initialize " + f.getName());
}
}
}
for (Field f : Libraries.class.getDeclaredFields()) {
if ((f.getModifiers() & Modifier.STATIC) == 0 && f.getType() == LibraryDownloader.class) {
try {
init(f, cfg);
} catch (IllegalArgumentException
| IllegalAccessException
| NoSuchFieldException
| SecurityException e) {
throw new IllegalStateException("Cannot configure " + f.getName());
}
}
}
}
private void init(Field field, Config cfg)
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException,
SecurityException {
String n = field.getName();
LibraryDownloader dl = (LibraryDownloader) field.get(this);
dl.setName(get(cfg, n, "name"));
dl.setJarUrl(get(cfg, n, "url"));
dl.setSHA1(getOptional(cfg, n, "sha1"));
dl.setRemove(get(cfg, n, "remove"));
for (String d : cfg.getStringList("library", n, "needs")) {
dl.addNeeds((LibraryDownloader) getClass().getDeclaredField(d).get(this));
}
dl.setSkipDownload(skipAllDownloads || skippedDownloads.contains(n));
}
private static String getOptional(Config cfg, String name, String key) {
return doGet(cfg, name, key, false);
}
private static String get(Config cfg, String name, String key) {
return doGet(cfg, name, key, true);
}
private static String doGet(Config cfg, String name, String key, boolean required) {
String val = cfg.getString("library", name, key);
if ((val == null || val.isEmpty()) && required) {
throw new IllegalStateException(
"Variable library." + name + "." + key + " is required within " + RESOURCE_FILE);
}
return val;
}
private static String read(String p) throws IOException {
try (InputStream in = Libraries.class.getClassLoader().getResourceAsStream(p)) {
if (in == null) {
throw new FileNotFoundException("Cannot load resource " + p);
}
try (Reader r = new InputStreamReader(in, UTF_8)) {
final StringBuilder buf = new StringBuilder();
final char[] tmp = new char[512];
int n;
while (0 < (n = r.read(tmp))) {
buf.append(tmp, 0, n);
}
return buf.toString();
}
}
}
}

View File

@@ -1,316 +0,0 @@
// Copyright (C) 2009 The Android Open Source Project
//
// 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 com.google.gerrit.pgm.init;
import com.google.common.hash.Funnels;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteStreams;
import com.google.gerrit.common.Die;
import com.google.gerrit.common.IoUtil;
import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jgit.util.HttpSupport;
/** Get optional or required 3rd party library files into $site_path/lib. */
class LibraryDownloader {
private final ConsoleUI ui;
private final Path lib_dir;
private final StaleLibraryRemover remover;
private boolean required;
private String name;
private String jarUrl;
private String sha1;
private String remove;
private List<LibraryDownloader> needs;
private LibraryDownloader neededBy;
private Path dst;
private boolean download; // download or copy
private boolean exists;
private boolean skipDownload;
@Inject
LibraryDownloader(ConsoleUI ui, SitePaths site, StaleLibraryRemover remover) {
this.ui = ui;
this.lib_dir = site.lib_dir;
this.remover = remover;
this.needs = new ArrayList<>(2);
}
void setName(String name) {
this.name = name;
}
void setJarUrl(String url) {
this.jarUrl = url;
download = jarUrl.startsWith("http");
}
void setSHA1(String sha1) {
this.sha1 = sha1;
}
void setRemove(String remove) {
this.remove = remove;
}
void addNeeds(LibraryDownloader lib) {
needs.add(lib);
}
void setSkipDownload(boolean skipDownload) {
this.skipDownload = skipDownload;
}
void downloadRequired() {
setRequired(true);
download();
}
void downloadOptional() {
required = false;
download();
}
private void setRequired(boolean r) {
required = r;
for (LibraryDownloader d : needs) {
d.setRequired(r);
}
}
private void download() {
if (skipDownload) {
return;
}
if (jarUrl == null || !jarUrl.contains("/")) {
throw new IllegalStateException("Invalid JarUrl for " + name);
}
final String jarName = jarUrl.substring(jarUrl.lastIndexOf('/') + 1);
if (jarName.contains("/") || jarName.contains("\\")) {
throw new IllegalStateException("Invalid JarUrl: " + jarUrl);
}
if (name == null) {
name = jarName;
}
dst = lib_dir.resolve(jarName);
if (Files.exists(dst)) {
exists = true;
} else if (shouldGet()) {
doGet();
}
if (exists) {
for (LibraryDownloader d : needs) {
d.neededBy = this;
d.downloadRequired();
}
}
}
private boolean shouldGet() {
if (ui.isBatch()) {
return required;
}
final StringBuilder msg = new StringBuilder();
msg.append("\n");
msg.append("Gerrit Code Review is not shipped with %s\n");
if (neededBy != null) {
msg.append(String.format("** This library is required by %s. **\n", neededBy.name));
} else if (required) {
msg.append("** This library is required for your configuration. **\n");
} else {
msg.append(" If available, Gerrit can take advantage of features\n");
msg.append(" in the library, but will also function without it.\n");
}
msg.append(String.format("%s and install it now", download ? "Download" : "Copy"));
return ui.yesno(true, msg.toString(), name);
}
private void doGet() {
if (!Files.exists(lib_dir)) {
try {
Files.createDirectories(lib_dir);
} catch (IOException e) {
throw new Die("Cannot create " + lib_dir, e);
}
}
try {
remover.remove(remove);
if (download) {
doGetByHttp();
} else {
doGetByLocalCopy();
}
verifyFileChecksum();
} catch (IOException err) {
try {
Files.delete(dst);
} catch (IOException e) {
// Delete failed; leave alone.
}
if (ui.isBatch()) {
throw new Die("error: Cannot get " + jarUrl, err);
}
System.err.println();
System.err.println();
System.err.println("error: " + err.getMessage());
System.err.println("Please download:");
System.err.println();
System.err.println(" " + jarUrl);
System.err.println();
System.err.println("and save as:");
System.err.println();
System.err.println(" " + dst.toAbsolutePath());
System.err.println();
System.err.flush();
ui.waitForUser();
if (Files.exists(dst)) {
verifyFileChecksum();
} else if (!ui.yesno(!required, "Continue without this library")) {
throw new Die("aborted by user");
}
}
if (Files.exists(dst)) {
exists = true;
IoUtil.loadJARs(dst);
}
}
private void doGetByLocalCopy() throws IOException {
System.err.print("Copying " + jarUrl + " ...");
Path p = url2file(jarUrl);
if (!Files.exists(p)) {
StringBuilder msg =
new StringBuilder()
.append("\n")
.append("Can not find the %s at this location: %s\n")
.append("Please provide alternative URL");
p = url2file(ui.readString(null, msg.toString(), name, jarUrl));
}
Files.copy(p, dst);
}
private static Path url2file(String urlString) throws IOException {
final URL url = new URL(urlString);
try {
return Paths.get(url.toURI());
} catch (URISyntaxException e) {
return Paths.get(url.getPath());
}
}
private void doGetByHttp() throws IOException {
System.err.print("Downloading " + jarUrl + " ...");
System.err.flush();
try (InputStream in = openHttpStream(jarUrl);
OutputStream out = Files.newOutputStream(dst)) {
ByteStreams.copy(in, out);
System.err.println(" OK");
System.err.flush();
} catch (IOException err) {
deleteDst();
System.err.println(" !! FAIL !!");
System.err.println(err);
System.err.flush();
throw err;
}
}
private static InputStream openHttpStream(String urlStr) throws IOException {
ProxySelector proxySelector = ProxySelector.getDefault();
URL url = new URL(urlStr);
Proxy proxy = HttpSupport.proxyFor(proxySelector, url);
HttpURLConnection c = (HttpURLConnection) url.openConnection(proxy);
switch (HttpSupport.response(c)) {
case HttpURLConnection.HTTP_OK:
return c.getInputStream();
case HttpURLConnection.HTTP_NOT_FOUND:
throw new FileNotFoundException(url.toString());
default:
throw new IOException(
url.toString() + ": " + HttpSupport.response(c) + " " + c.getResponseMessage());
}
}
@SuppressWarnings("deprecation") // Use Hashing.sha1 for compatibility.
private void verifyFileChecksum() {
if (sha1 == null) {
System.err.println();
System.err.flush();
return;
}
Hasher h = Hashing.sha1().newHasher();
try (InputStream in = Files.newInputStream(dst);
OutputStream out = Funnels.asOutputStream(h)) {
ByteStreams.copy(in, out);
} catch (IOException e) {
deleteDst();
throw new Die("cannot checksum " + dst, e);
}
if (sha1.equals(h.hash().toString())) {
System.err.println("Checksum " + dst.getFileName() + " OK");
System.err.flush();
} else if (ui.isBatch()) {
deleteDst();
throw new Die(dst + " SHA-1 checksum does not match");
} else if (!ui.yesno(
null /* force an answer */,
"error: SHA-1 checksum does not match\nUse %s anyway", //
dst.getFileName())) {
deleteDst();
throw new Die("aborted by user");
}
}
private void deleteDst() {
try {
Files.delete(dst);
} catch (IOException e) {
System.err.println(" Failed to clean up lib: " + dst);
}
}
}

View File

@@ -51,6 +51,7 @@ import java.sql.Timestamp;
import java.util.List;
import java.util.Optional;
import java.util.TimeZone;
import org.eclipse.jgit.dircache.InvalidPathException;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.NullProgressMonitor;
@@ -243,13 +244,14 @@ public class ChangeEditModifier {
* @param filePath the path of the file whose contents should be modified
* @param newContent the new file content
* @throws AuthException if the user isn't authenticated or not allowed to use change edits
* @throws BadRequestException if the user provided bad input (e.g. invalid file paths)
* @throws InvalidChangeOperationException if the file already had the specified content
* @throws PermissionBackendException
* @throws ResourceConflictException if the project state does not permit the operation
*/
public void modifyFile(
Repository repository, ChangeNotes notes, String filePath, RawInput newContent)
throws AuthException, InvalidChangeOperationException, IOException,
throws AuthException, BadRequestException, InvalidChangeOperationException, IOException,
PermissionBackendException, ResourceConflictException {
modifyTree(repository, notes, new ChangeFileContentModification(filePath, newContent));
}
@@ -262,12 +264,13 @@ public class ChangeEditModifier {
* @param notes the {@link ChangeNotes} of the change whose change edit should be modified
* @param file path of the file which should be deleted
* @throws AuthException if the user isn't authenticated or not allowed to use change edits
* @throws BadRequestException if the user provided bad input (e.g. invalid file paths)
* @throws InvalidChangeOperationException if the file does not exist
* @throws PermissionBackendException
* @throws ResourceConflictException if the project state does not permit the operation
*/
public void deleteFile(Repository repository, ChangeNotes notes, String file)
throws AuthException, InvalidChangeOperationException, IOException,
throws AuthException, BadRequestException, InvalidChangeOperationException, IOException,
PermissionBackendException, ResourceConflictException {
modifyTree(repository, notes, new DeleteFileModification(file));
}
@@ -281,6 +284,7 @@ public class ChangeEditModifier {
* @param currentFilePath the current path/name of the file
* @param newFilePath the desired path/name of the file
* @throws AuthException if the user isn't authenticated or not allowed to use change edits
* @throws BadRequestException if the user provided bad input (e.g. invalid file paths)
* @throws InvalidChangeOperationException if the file was already renamed to the specified new
* name
* @throws PermissionBackendException
@@ -288,7 +292,7 @@ public class ChangeEditModifier {
*/
public void renameFile(
Repository repository, ChangeNotes notes, String currentFilePath, String newFilePath)
throws AuthException, InvalidChangeOperationException, IOException,
throws AuthException, BadRequestException, InvalidChangeOperationException, IOException,
PermissionBackendException, ResourceConflictException {
modifyTree(repository, notes, new RenameFileModification(currentFilePath, newFilePath));
}
@@ -306,14 +310,14 @@ public class ChangeEditModifier {
* @throws PermissionBackendException
*/
public void restoreFile(Repository repository, ChangeNotes notes, String file)
throws AuthException, InvalidChangeOperationException, IOException,
throws AuthException, BadRequestException, InvalidChangeOperationException, IOException,
PermissionBackendException, ResourceConflictException {
modifyTree(repository, notes, new RestoreFileModification(file));
}
private void modifyTree(
Repository repository, ChangeNotes notes, TreeModification treeModification)
throws AuthException, IOException, InvalidChangeOperationException,
throws AuthException, BadRequestException, IOException, InvalidChangeOperationException,
PermissionBackendException, ResourceConflictException {
assertCanEdit(notes);
@@ -358,8 +362,8 @@ public class ChangeEditModifier {
ChangeNotes notes,
PatchSet patchSet,
List<TreeModification> treeModifications)
throws AuthException, IOException, InvalidChangeOperationException, MergeConflictException,
PermissionBackendException, ResourceConflictException {
throws AuthException, BadRequestException, IOException, InvalidChangeOperationException,
MergeConflictException, PermissionBackendException, ResourceConflictException {
assertCanEdit(notes);
Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(notes);
@@ -469,10 +473,15 @@ public class ChangeEditModifier {
private static ObjectId createNewTree(
Repository repository, RevCommit baseCommit, List<TreeModification> treeModifications)
throws IOException, InvalidChangeOperationException {
TreeCreator treeCreator = new TreeCreator(baseCommit);
treeCreator.addTreeModifications(treeModifications);
ObjectId newTreeId = treeCreator.createNewTreeAndGetId(repository);
throws BadRequestException, IOException, InvalidChangeOperationException {
ObjectId newTreeId;
try {
TreeCreator treeCreator = new TreeCreator(baseCommit);
treeCreator.addTreeModifications(treeModifications);
newTreeId = treeCreator.createNewTreeAndGetId(repository);
} catch (InvalidPathException e) {
throw new BadRequestException(e.getMessage());
}
if (ObjectId.isEqual(newTreeId, baseCommit.getTree())) {
throw new InvalidChangeOperationException("no changes were made");

View File

@@ -18,6 +18,7 @@ import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.common.EditInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.Response;
@@ -65,8 +66,8 @@ public class ApplyFix implements RestModifyView<FixResource, Void> {
@Override
public Response<EditInfo> apply(FixResource fixResource, Void nothing)
throws AuthException, ResourceConflictException, IOException, ResourceNotFoundException,
PermissionBackendException {
throws AuthException, BadRequestException, ResourceConflictException, IOException,
ResourceNotFoundException, PermissionBackendException {
RevisionResource revisionResource = fixResource.getRevisionResource();
Project.NameKey project = revisionResource.getProject();
ProjectState projectState = projectCache.checkedGet(project);

View File

@@ -118,7 +118,8 @@ public class ChangeEdits implements ChildCollection<ChangeResource, ChangeEditRe
@Override
public Response<?> apply(ChangeResource resource, IdString id, Put.Input input)
throws AuthException, ResourceConflictException, IOException, PermissionBackendException {
throws AuthException, ResourceConflictException, BadRequestException, IOException,
PermissionBackendException {
putEdit.apply(resource, id.get(), input.content);
return Response.none();
}
@@ -135,7 +136,8 @@ public class ChangeEdits implements ChildCollection<ChangeResource, ChangeEditRe
@Override
public Response<?> apply(ChangeResource rsrc, IdString id, Input in)
throws IOException, AuthException, ResourceConflictException, PermissionBackendException {
throws IOException, AuthException, BadRequestException, ResourceConflictException,
PermissionBackendException {
return deleteContent.apply(rsrc, id.get());
}
}
@@ -236,7 +238,8 @@ public class ChangeEdits implements ChildCollection<ChangeResource, ChangeEditRe
@Override
public Response<?> apply(ChangeResource resource, Post.Input input)
throws AuthException, IOException, ResourceConflictException, PermissionBackendException {
throws AuthException, BadRequestException, IOException, ResourceConflictException,
PermissionBackendException {
Project.NameKey project = resource.getProject();
try (Repository repository = repositoryManager.openRepository(project)) {
if (isRestoreFile(input)) {
@@ -281,12 +284,14 @@ public class ChangeEdits implements ChildCollection<ChangeResource, ChangeEditRe
@Override
public Response<?> apply(ChangeEditResource rsrc, Input input)
throws AuthException, ResourceConflictException, IOException, PermissionBackendException {
throws AuthException, ResourceConflictException, BadRequestException, IOException,
PermissionBackendException {
return apply(rsrc.getChangeResource(), rsrc.getPath(), input.content);
}
public Response<?> apply(ChangeResource rsrc, String path, RawInput newContent)
throws ResourceConflictException, AuthException, IOException, PermissionBackendException {
throws ResourceConflictException, AuthException, BadRequestException, IOException,
PermissionBackendException {
if (Strings.isNullOrEmpty(path) || path.charAt(0) == '/') {
throw new ResourceConflictException("Invalid path: " + path);
}
@@ -320,12 +325,14 @@ public class ChangeEdits implements ChildCollection<ChangeResource, ChangeEditRe
@Override
public Response<?> apply(ChangeEditResource rsrc, Input input)
throws AuthException, ResourceConflictException, IOException, PermissionBackendException {
throws AuthException, BadRequestException, ResourceConflictException, IOException,
PermissionBackendException {
return apply(rsrc.getChangeResource(), rsrc.getPath());
}
public Response<?> apply(ChangeResource rsrc, String filePath)
throws AuthException, IOException, ResourceConflictException, PermissionBackendException {
throws AuthException, BadRequestException, IOException, ResourceConflictException,
PermissionBackendException {
try (Repository repository = repositoryManager.openRepository(rsrc.getProject())) {
editModifier.deleteFile(repository, rsrc.getNotes(), filePath);
} catch (InvalidChangeOperationException e) {

View File

@@ -58,6 +58,7 @@ import com.google.gerrit.extensions.common.DiffInfo;
import com.google.gerrit.extensions.common.EditInfo;
import com.google.gerrit.extensions.common.FileInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.server.ChangeMessagesUtil;
@@ -435,6 +436,16 @@ public class ChangeEditIT extends AbstractDaemonTest {
assertThat(getFileContentOfEdit(changeId, FILE_NAME)).isAbsent();
}
@Test
public void renameExistingFileToInvalidPath() throws Exception {
createEmptyEditFor(changeId);
BadRequestException badRequest =
assertThrows(
BadRequestException.class,
() -> gApi.changes().id(changeId).edit().renameFile(FILE_NAME, "invalid/path/"));
assertThat(badRequest.getMessage()).isEqualTo("Invalid path: invalid/path/");
}
@Test
public void createEditByDeletingExistingFileRest() throws Exception {
adminRestSession.delete(urlEditFile(changeId, FILE_NAME)).assertNoContent();

View File

@@ -1,46 +0,0 @@
// Copyright (C) 2009 The Android Open Source Project
//
// 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 com.google.gerrit.pgm.init;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.verifyZeroInteractions;
import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.server.config.SitePaths;
import java.nio.file.Paths;
import java.util.Collections;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class LibrariesTest {
@Mock ConsoleUI ui;
@Mock StaleLibraryRemover remover;
@Test
public void create() throws Exception {
final SitePaths site = new SitePaths(Paths.get("."));
Libraries lib =
new Libraries(
() -> new LibraryDownloader(ui, site, remover), Collections.emptyList(), false);
assertNotNull(lib.mysqlDriver);
verifyZeroInteractions(ui);
verifyZeroInteractions(remover);
}
}

View File

@@ -1,50 +0,0 @@
# Copyright (C) 2009 The Android Open Source Project
#
# 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.
[library "mysqlDriver"]
name = MySQL Connector/J 5.1.43
url = https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.43/mysql-connector-java-5.1.43.jar
sha1 = dee9103eec0d877f3a21c82d4d9e9f4fbd2d6e0a
remove = mysql-connector-java-.*[.]jar
[library "mariadbDriver"]
name = MariaDB Connector/J 2.3.0
url = https://repo1.maven.org/maven2/org/mariadb/jdbc/mariadb-java-client/2.3.0/mariadb-java-client-2.3.0.jar
sha1 = c2b1a6002a169757d0649449288e9b3b776af76b
remove = mariadb-java-client-.*[.]jar
[library "oracleDriver"]
name = Oracle JDBC driver 11g Release 2 (11.2.0)
url = file:///u01/app/oracle/product/11.2.0/xe/jdbc/lib/ojdbc6.jar
sha1 = 2f89cd9176772c3a6c261ce6a8e3d0d4425f5679
remove = ojdbc6.jar
[library "db2Driver"]
name = DB2 Type 4 JDBC driver (10.5)
url = file:///opt/ibm/db2/V10.5/java/db2jcc4.jar
sha1 = 9344d4fd41d6511f2d1d1deb7759056495b3a39b
needs = db2DriverLicense
remove = db2jcc4.jar
# Omit SHA-1 for license JAR as it's not stable and depends on the product
# the customer has purchased.
[library "db2DriverLicense"]
name = DB2 Type 4 JDBC driver license (10.5)
url = file:///opt/ibm/db2/V10.5/java/db2jcc_license_cu.jar
remove = db2jcc_license_cu.jar
[library "hanaDriver"]
name = HANA JDBC driver
url = file:///usr/sap/hdbclient/ngdbc.jar
remove = ngdbc.jar