Merge branch 'stable-2.15'

* stable-2.15:
  ChangeIT: Move reflog test to ReflogIT
  ReflogIT: Move to com.google.gerrit.acceptance.server.project
  ReflogIT: Remove unneeded setUp method
  ChangeIT: Fix and expand reflog test
  ProjectState: Remove unnecessary 'final' modifiers from constructor
  ConfigInfo: Annotate MaxObjectSizeLimitInfo fields as nullable
  ConfigInfo: Add Javadoc for MaxObjectSizeLimitInfo fields
  Upgrade JGit to v4.5.4.201711221230-r
  Fix deprecation warnings from latest JGit update
  Upgrade JGit to 4.3.0.201604071810-r
  Set version to 2.12.9-SNAPSHOT
  Buck: Fix typo in gerrit_plugin.bucklet
  Remove min width from autocomplete container
  ConfigInfoImpl: Factor out initialization of MaxObjectSizeLimitInfo to a method
  Rename instances of TransferConfig to transferConfig
  Clarify inherited_value in documentation of MaxObjectSizeLimitInfo
  Reword docmentation of project specific object size limit for clarity
  PutConfig: Reload project config before returning response
  Fix partially hidden plugin configuration in the UI
  Upgrade PostgreSQL JDBC driver
  SiteProgram: Extract local variable
  SiteProgram: Extract constant
  SiteProgram: Inline variable to avoid hiding field
  DataSourceProvider: Rename local variable to avoid hiding field
  DataSourceProvider: Remove unneeded finals
  DataSourceProvider: Replace inner class with lambda
  DataSourceProvider: Extract constant
  Add current patchset to json when a review is public/ready
  Migrate `tools/bazel.rc` to `.bazelrc`
  ProjectIT: Add tests for maxObjectSize configuration
  EventRecorder: Add assertNoRefUpdatedEvents helper method
  ProjectIT: Rename 'config' method to 'submitType'

Change-Id: I83eee5496f538daff37c936dcb1cc19f13b27705
This commit is contained in:
David Pursehouse
2018-08-15 13:39:59 +01:00
24 changed files with 277 additions and 92 deletions

View File

@@ -144,9 +144,12 @@ objects which are too large to Gerrit. This setting can also be set in
`gerrit.config` globally (link:config-gerrit.html#receive.maxObjectSizeLimit[ `gerrit.config` globally (link:config-gerrit.html#receive.maxObjectSizeLimit[
receive.maxObjectSizeLimit]). receive.maxObjectSizeLimit]).
+ +
The project specific setting in `project.config` is only honored when it The project specific setting in `project.config` may not set a value higher
further reduces the global limit. The setting is not inherited from the than the global limit (if configured). In other words, it is only honored when
parent project; it must be explicitly set per project. it further reduces the global limit.
+
The setting is not inherited from the parent project; it must be explicitly
set per project.
+ +
Default is zero. Default is zero.
+ +

View File

@@ -3278,7 +3278,8 @@ formatted string. +
Not set if there is no limit for the object size configured on project Not set if there is no limit for the object size configured on project
level. level.
|`inherited_value` |optional| |`inherited_value` |optional|
The max object size limit that is inherited as a formatted string. + The max object size limit that is inherited from the global config as a
formatted string. +
Not set if there is no global limit for the object size. Not set if there is no global limit for the object size.
|=============================== |===============================

View File

@@ -861,8 +861,8 @@ maven_jar(
maven_jar( maven_jar(
name = "postgresql", name = "postgresql",
artifact = "org.postgresql:postgresql:9.4.1211", artifact = "org.postgresql:postgresql:42.2.4",
sha1 = "721e3017fab68db9f0b08537ec91b8d757973ca8", sha1 = "dff98730c28a4b3a3263f0cf4abb9a3392f815a7",
) )
maven_jar( maven_jar(

View File

@@ -512,6 +512,9 @@ public class ProjectInfoScreen extends ProjectScreen {
textBox.setValue(param.value()); textBox.setValue(param.value());
addWidget(g, textBox, param); addWidget(g, textBox, param);
} }
if (textBox.getValue().length() > textBox.getVisibleLength()) {
textBox.setVisibleLength(textBox.getValue().length());
}
saveEnabler.listenTo(textBox); saveEnabler.listenTo(textBox);
return textBox; return textBox;
} }

View File

@@ -137,6 +137,10 @@ public class EventRecorder {
return events; return events;
} }
public void assertNoRefUpdatedEvents(String project, String branch) throws Exception {
getRefUpdatedEvents(project, branch, 0);
}
public void assertRefUpdatedEvents(String project, String branch, String... expected) public void assertRefUpdatedEvents(String project, String branch, String... expected)
throws Exception { throws Exception {
ImmutableList<RefUpdatedEvent> events = ImmutableList<RefUpdatedEvent> events =

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.extensions.api.projects; package com.google.gerrit.extensions.api.projects;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.client.InheritableBoolean; import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.ProjectState; import com.google.gerrit.extensions.client.ProjectState;
import com.google.gerrit.extensions.client.SubmitType; import com.google.gerrit.extensions.client.SubmitType;
@@ -58,9 +59,14 @@ public class ConfigInfo {
} }
public static class MaxObjectSizeLimitInfo { public static class MaxObjectSizeLimitInfo {
public String value; /* The effective value. Null if not set. */
public String configuredValue; @Nullable public String value;
public String inheritedValue;
/* The value configured on the project. Null if not set. */
@Nullable public String configuredValue;
/* The value configured globally. Null if not set. */
@Nullable public String inheritedValue;
} }
public static class ConfigParameterInfo { public static class ConfigParameterInfo {

View File

@@ -15,7 +15,7 @@
package com.google.gerrit.extensions.events; package com.google.gerrit.extensions.events;
public interface PrivateStateChangedListener { public interface PrivateStateChangedListener {
interface Event extends ChangeEvent {} interface Event extends RevisionEvent {}
void onPrivateStateChanged(Event event); void onPrivateStateChanged(Event event);
} }

View File

@@ -15,7 +15,7 @@
package com.google.gerrit.extensions.events; package com.google.gerrit.extensions.events;
public interface WorkInProgressStateChangedListener { public interface WorkInProgressStateChangedListener {
interface Event extends ChangeEvent {} interface Event extends RevisionEvent {}
void onWorkInProgressStateChanged(Event event); void onWorkInProgressStateChanged(Event event);
} }

View File

@@ -64,6 +64,8 @@ import org.eclipse.jgit.lib.Config;
import org.kohsuke.args4j.Option; import org.kohsuke.args4j.Option;
public abstract class SiteProgram extends AbstractProgram { public abstract class SiteProgram extends AbstractProgram {
private static final String CONNECTION_ERROR = "Cannot connect to SQL database";
@Option( @Option(
name = "--site-path", name = "--site-path",
aliases = {"-d"}, aliases = {"-d"},
@@ -106,14 +108,13 @@ public abstract class SiteProgram extends AbstractProgram {
/** @return provides database connectivity and site path. */ /** @return provides database connectivity and site path. */
protected Injector createDbInjector(boolean enableMetrics, DataSourceProvider.Context context) { protected Injector createDbInjector(boolean enableMetrics, DataSourceProvider.Context context) {
Path sitePath = getSitePath();
List<Module> modules = new ArrayList<>(); List<Module> modules = new ArrayList<>();
Module sitePathModule = Module sitePathModule =
new AbstractModule() { new AbstractModule() {
@Override @Override
protected void configure() { protected void configure() {
bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath); bind(Path.class).annotatedWith(SitePath.class).toInstance(getSitePath());
bind(String.class) bind(String.class)
.annotatedWith(SecureStoreClassName.class) .annotatedWith(SecureStoreClassName.class)
.toProvider(Providers.of(getConfiguredSecureStoreClass())); .toProvider(Providers.of(getConfiguredSecureStoreClass()));
@@ -198,16 +199,16 @@ public abstract class SiteProgram extends AbstractProgram {
Throwable why = first.getCause(); Throwable why = first.getCause();
if (why instanceof SQLException) { if (why instanceof SQLException) {
throw die("Cannot connect to SQL database", why); throw die(CONNECTION_ERROR, why);
} }
if (why instanceof OrmException if (why instanceof OrmException
&& why.getCause() != null && why.getCause() != null
&& "Unable to determine driver URL".equals(why.getMessage())) { && "Unable to determine driver URL".equals(why.getMessage())) {
why = why.getCause(); why = why.getCause();
if (isCannotCreatePoolException(why)) { if (isCannotCreatePoolException(why)) {
throw die("Cannot connect to SQL database", why.getCause()); throw die(CONNECTION_ERROR, why.getCause());
} }
throw die("Cannot connect to SQL database", why); throw die(CONNECTION_ERROR, why);
} }
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
@@ -259,8 +260,9 @@ public abstract class SiteProgram extends AbstractProgram {
for (Binding<DataSourceType> binding : dsTypeBindings) { for (Binding<DataSourceType> binding : dsTypeBindings) {
Annotation annotation = binding.getKey().getAnnotation(); Annotation annotation = binding.getKey().getAnnotation();
if (annotation instanceof Named) { if (annotation instanceof Named) {
if (((Named) annotation).value().toLowerCase().contains(dbProductName)) { Named named = (Named) annotation;
return ((Named) annotation).value(); if (named.value().toLowerCase().contains(dbProductName)) {
return named.value();
} }
} }
} }

View File

@@ -125,7 +125,7 @@ public class WorkInProgressOp implements BatchUpdateOp {
@Override @Override
public void postUpdate(Context ctx) { public void postUpdate(Context ctx) {
stateChanged.fire(change, ctx.getAccount(), ctx.getWhen()); stateChanged.fire(change, ps, ctx.getAccount(), ctx.getWhen());
if (workInProgress || notify.ordinal() < NotifyHandling.OWNER_REVIEWERS.ordinal()) { if (workInProgress || notify.ordinal() < NotifyHandling.OWNER_REVIEWERS.ordinal()) {
return; return;
} }

View File

@@ -18,7 +18,7 @@ import com.google.common.base.Supplier;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.data.AccountAttribute; import com.google.gerrit.server.data.AccountAttribute;
public class PrivateStateChangedEvent extends ChangeEvent { public class PrivateStateChangedEvent extends PatchSetEvent {
static final String TYPE = "private-state-changed"; static final String TYPE = "private-state-changed";
public Supplier<AccountAttribute> changer; public Supplier<AccountAttribute> changer;

View File

@@ -472,10 +472,12 @@ public class StreamEventsApiListener
try { try {
ChangeNotes notes = getNotes(ev.getChange()); ChangeNotes notes = getNotes(ev.getChange());
Change change = notes.getChange(); Change change = notes.getChange();
PatchSet patchSet = getPatchSet(notes, ev.getRevision());
WorkInProgressStateChangedEvent event = new WorkInProgressStateChangedEvent(change); WorkInProgressStateChangedEvent event = new WorkInProgressStateChangedEvent(change);
event.change = changeAttributeSupplier(change, notes); event.change = changeAttributeSupplier(change, notes);
event.changer = accountAttributeSupplier(ev.getWho()); event.changer = accountAttributeSupplier(ev.getWho());
event.patchSet = patchSetAttributeSupplier(change, patchSet);
dispatcher.get().postEvent(change, event); dispatcher.get().postEvent(change, event);
} catch (OrmException | PermissionBackendException e) { } catch (OrmException | PermissionBackendException e) {
@@ -488,10 +490,12 @@ public class StreamEventsApiListener
try { try {
ChangeNotes notes = getNotes(ev.getChange()); ChangeNotes notes = getNotes(ev.getChange());
Change change = notes.getChange(); Change change = notes.getChange();
PatchSet patchSet = getPatchSet(notes, ev.getRevision());
PrivateStateChangedEvent event = new PrivateStateChangedEvent(change); PrivateStateChangedEvent event = new PrivateStateChangedEvent(change);
event.change = changeAttributeSupplier(change, notes); event.change = changeAttributeSupplier(change, notes);
event.changer = accountAttributeSupplier(ev.getWho()); event.changer = accountAttributeSupplier(ev.getWho());
event.patchSet = patchSetAttributeSupplier(change, patchSet);
dispatcher.get().postEvent(change, event); dispatcher.get().postEvent(change, event);
} catch (OrmException | PermissionBackendException e) { } catch (OrmException | PermissionBackendException e) {

View File

@@ -18,7 +18,7 @@ import com.google.common.base.Supplier;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.data.AccountAttribute; import com.google.gerrit.server.data.AccountAttribute;
public class WorkInProgressStateChangedEvent extends ChangeEvent { public class WorkInProgressStateChangedEvent extends PatchSetEvent {
static final String TYPE = "wip-state-changed"; static final String TYPE = "wip-state-changed";
public Supplier<AccountAttribute> changer; public Supplier<AccountAttribute> changer;

View File

@@ -18,13 +18,19 @@ import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.api.changes.NotifyHandling; import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.common.AccountInfo; import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo; import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.events.PrivateStateChangedListener; import com.google.gerrit.extensions.events.PrivateStateChangedListener;
import com.google.gerrit.extensions.registration.DynamicSet; import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
import com.google.gerrit.server.account.AccountState; import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import java.io.IOException;
import java.sql.Timestamp; import java.sql.Timestamp;
@Singleton @Singleton
@@ -40,12 +46,17 @@ public class PrivateStateChanged {
this.util = util; this.util = util;
} }
public void fire(Change change, AccountState account, Timestamp when) { public void fire(Change change, PatchSet patchSet, AccountState account, Timestamp when) {
if (!listeners.iterator().hasNext()) { if (!listeners.iterator().hasNext()) {
return; return;
} }
try { try {
Event event = new Event(util.changeInfo(change), util.accountInfo(account), when); Event event =
new Event(
util.changeInfo(change),
util.revisionInfo(change.getProject(), patchSet),
util.accountInfo(account),
when);
for (PrivateStateChangedListener l : listeners) { for (PrivateStateChangedListener l : listeners) {
try { try {
l.onPrivateStateChanged(event); l.onPrivateStateChanged(event);
@@ -53,16 +64,20 @@ public class PrivateStateChanged {
util.logEventListenerError(event, l, e); util.logEventListenerError(event, l, e);
} }
} }
} catch (OrmException e) { } catch (OrmException
| PatchListNotAvailableException
| GpgException
| IOException
| PermissionBackendException e) {
logger.atSevere().withCause(e).log("Couldn't fire event"); logger.atSevere().withCause(e).log("Couldn't fire event");
} }
} }
private static class Event extends AbstractChangeEvent private static class Event extends AbstractRevisionEvent
implements PrivateStateChangedListener.Event { implements PrivateStateChangedListener.Event {
protected Event(ChangeInfo change, AccountInfo who, Timestamp when) { protected Event(ChangeInfo change, RevisionInfo revision, AccountInfo who, Timestamp when) {
super(change, who, when, NotifyHandling.ALL); super(change, revision, who, when, NotifyHandling.ALL);
} }
} }
} }

View File

@@ -18,13 +18,19 @@ import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.api.changes.NotifyHandling; import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.common.AccountInfo; import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo; import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.events.WorkInProgressStateChangedListener; import com.google.gerrit.extensions.events.WorkInProgressStateChangedListener;
import com.google.gerrit.extensions.registration.DynamicSet; import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
import com.google.gerrit.server.account.AccountState; import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import java.io.IOException;
import java.sql.Timestamp; import java.sql.Timestamp;
@Singleton @Singleton
@@ -41,12 +47,17 @@ public class WorkInProgressStateChanged {
this.util = util; this.util = util;
} }
public void fire(Change change, AccountState account, Timestamp when) { public void fire(Change change, PatchSet patchSet, AccountState account, Timestamp when) {
if (!listeners.iterator().hasNext()) { if (!listeners.iterator().hasNext()) {
return; return;
} }
try { try {
Event event = new Event(util.changeInfo(change), util.accountInfo(account), when); Event event =
new Event(
util.changeInfo(change),
util.revisionInfo(change.getProject(), patchSet),
util.accountInfo(account),
when);
for (WorkInProgressStateChangedListener l : listeners) { for (WorkInProgressStateChangedListener l : listeners) {
try { try {
l.onWorkInProgressStateChanged(event); l.onWorkInProgressStateChanged(event);
@@ -54,16 +65,20 @@ public class WorkInProgressStateChanged {
util.logEventListenerError(event, l, e); util.logEventListenerError(event, l, e);
} }
} }
} catch (OrmException e) { } catch (OrmException
| PatchListNotAvailableException
| GpgException
| IOException
| PermissionBackendException e) {
logger.atSevere().withCause(e).log("Couldn't fire event"); logger.atSevere().withCause(e).log("Couldn't fire event");
} }
} }
private static class Event extends AbstractChangeEvent private static class Event extends AbstractRevisionEvent
implements WorkInProgressStateChangedListener.Event { implements WorkInProgressStateChangedListener.Event {
protected Event(ChangeInfo change, AccountInfo who, Timestamp when) { protected Event(ChangeInfo change, RevisionInfo revision, AccountInfo who, Timestamp when) {
super(change, who, when, NotifyHandling.ALL); super(change, revision, who, when, NotifyHandling.ALL);
} }
} }
} }

View File

@@ -107,14 +107,14 @@ public class ProjectState {
@Inject @Inject
public ProjectState( public ProjectState(
final SitePaths sitePaths, SitePaths sitePaths,
final ProjectCache projectCache, ProjectCache projectCache,
final AllProjectsName allProjectsName, AllProjectsName allProjectsName,
final AllUsersName allUsersName, AllUsersName allUsersName,
final GitRepositoryManager gitMgr, GitRepositoryManager gitMgr,
final List<CommentLinkInfo> commentLinks, List<CommentLinkInfo> commentLinks,
final CapabilityCollection.Factory limitsFactory, CapabilityCollection.Factory limitsFactory,
@Assisted final ProjectConfig config) { @Assisted ProjectConfig config) {
this.sitePaths = sitePaths; this.sitePaths = sitePaths;
this.projectCache = projectCache; this.projectCache = projectCache;
this.isAllProjects = config.getProject().getNameKey().equals(allProjectsName); this.isAllProjects = config.getProject().getNameKey().equals(allProjectsName);

View File

@@ -18,8 +18,11 @@ import com.google.common.base.Strings;
import com.google.gerrit.extensions.restapi.ResourceConflictException; import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage; import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.ChangeMessagesUtil; import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.extensions.events.PrivateStateChanged; import com.google.gerrit.server.extensions.events.PrivateStateChanged;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate; import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.update.BatchUpdateOp; import com.google.gerrit.server.update.BatchUpdateOp;
import com.google.gerrit.server.update.ChangeContext; import com.google.gerrit.server.update.ChangeContext;
@@ -44,19 +47,23 @@ public class SetPrivateOp implements BatchUpdateOp {
} }
private final ChangeMessagesUtil cmUtil; private final ChangeMessagesUtil cmUtil;
private final PatchSetUtil psUtil;
private final boolean isPrivate; private final boolean isPrivate;
private final Input input; private final Input input;
private final PrivateStateChanged privateStateChanged; private final PrivateStateChanged privateStateChanged;
private Change change; private Change change;
private PatchSet ps;
@Inject @Inject
SetPrivateOp( SetPrivateOp(
PrivateStateChanged privateStateChanged, PrivateStateChanged privateStateChanged,
PatchSetUtil psUtil,
@Assisted ChangeMessagesUtil cmUtil, @Assisted ChangeMessagesUtil cmUtil,
@Assisted boolean isPrivate, @Assisted boolean isPrivate,
@Assisted Input input) { @Assisted Input input) {
this.cmUtil = cmUtil; this.cmUtil = cmUtil;
this.psUtil = psUtil;
this.isPrivate = isPrivate; this.isPrivate = isPrivate;
this.input = input; this.input = input;
this.privateStateChanged = privateStateChanged; this.privateStateChanged = privateStateChanged;
@@ -65,6 +72,8 @@ public class SetPrivateOp implements BatchUpdateOp {
@Override @Override
public boolean updateChange(ChangeContext ctx) throws ResourceConflictException, OrmException { public boolean updateChange(ChangeContext ctx) throws ResourceConflictException, OrmException {
change = ctx.getChange(); change = ctx.getChange();
ChangeNotes notes = ctx.getNotes();
ps = psUtil.get(ctx.getDb(), notes, change.currentPatchSetId());
ChangeUpdate update = ctx.getUpdate(change.currentPatchSetId()); ChangeUpdate update = ctx.getUpdate(change.currentPatchSetId());
change.setPrivate(isPrivate); change.setPrivate(isPrivate);
change.setLastUpdatedOn(ctx.getWhen()); change.setLastUpdatedOn(ctx.getWhen());
@@ -75,7 +84,7 @@ public class SetPrivateOp implements BatchUpdateOp {
@Override @Override
public void postUpdate(Context ctx) { public void postUpdate(Context ctx) {
privateStateChanged.fire(change, ctx.getAccount(), ctx.getWhen()); privateStateChanged.fire(change, ps, ctx.getAccount(), ctx.getWhen());
} }
private void addMessage(ChangeContext ctx, ChangeUpdate update) throws OrmException { private void addMessage(ChangeContext ctx, ChangeUpdate update) throws OrmException {

View File

@@ -48,7 +48,7 @@ public class ConfigInfoImpl extends ConfigInfo {
boolean serverEnableSignedPush, boolean serverEnableSignedPush,
ProjectState projectState, ProjectState projectState,
CurrentUser user, CurrentUser user,
TransferConfig config, TransferConfig transferConfig,
DynamicMap<ProjectConfigEntry> pluginConfigEntries, DynamicMap<ProjectConfigEntry> pluginConfigEntries,
PluginConfigFactory cfgFactory, PluginConfigFactory cfgFactory,
AllProjectsName allProjects, AllProjectsName allProjects,
@@ -72,14 +72,7 @@ public class ConfigInfoImpl extends ConfigInfo {
this.requireSignedPush = null; this.requireSignedPush = null;
} }
MaxObjectSizeLimitInfo maxObjectSizeLimit = new MaxObjectSizeLimitInfo(); this.maxObjectSizeLimit = getMaxObjectSizeLimit(projectState, transferConfig, p);
maxObjectSizeLimit.value =
config.getEffectiveMaxObjectSizeLimit(projectState) == config.getMaxObjectSizeLimit()
? config.getFormattedMaxObjectSizeLimit()
: p.getMaxObjectSizeLimit();
maxObjectSizeLimit.configuredValue = p.getMaxObjectSizeLimit();
maxObjectSizeLimit.inheritedValue = config.getFormattedMaxObjectSizeLimit();
this.maxObjectSizeLimit = maxObjectSizeLimit;
this.defaultSubmitType = new SubmitTypeInfo(); this.defaultSubmitType = new SubmitTypeInfo();
this.defaultSubmitType.value = projectState.getSubmitType(); this.defaultSubmitType.value = projectState.getSubmitType();
@@ -114,6 +107,19 @@ public class ConfigInfoImpl extends ConfigInfo {
this.extensionPanelNames = projectState.getConfig().getExtensionPanelSections(); this.extensionPanelNames = projectState.getConfig().getExtensionPanelSections();
} }
private MaxObjectSizeLimitInfo getMaxObjectSizeLimit(
ProjectState projectState, TransferConfig transferConfig, Project p) {
MaxObjectSizeLimitInfo info = new MaxObjectSizeLimitInfo();
info.value =
transferConfig.getEffectiveMaxObjectSizeLimit(projectState)
== transferConfig.getMaxObjectSizeLimit()
? transferConfig.getFormattedMaxObjectSizeLimit()
: p.getMaxObjectSizeLimit();
info.configuredValue = p.getMaxObjectSizeLimit();
info.inheritedValue = transferConfig.getFormattedMaxObjectSizeLimit();
return info;
}
private Map<String, Map<String, ConfigParameterInfo>> getPluginConfig( private Map<String, Map<String, ConfigParameterInfo>> getPluginConfig(
ProjectState project, ProjectState project,
DynamicMap<ProjectConfigEntry> pluginConfigEntries, DynamicMap<ProjectConfigEntry> pluginConfigEntries,

View File

@@ -31,7 +31,7 @@ import com.google.inject.Singleton;
@Singleton @Singleton
public class GetConfig implements RestReadView<ProjectResource> { public class GetConfig implements RestReadView<ProjectResource> {
private final boolean serverEnableSignedPush; private final boolean serverEnableSignedPush;
private final TransferConfig config; private final TransferConfig transferConfig;
private final DynamicMap<ProjectConfigEntry> pluginConfigEntries; private final DynamicMap<ProjectConfigEntry> pluginConfigEntries;
private final PluginConfigFactory cfgFactory; private final PluginConfigFactory cfgFactory;
private final AllProjectsName allProjects; private final AllProjectsName allProjects;
@@ -41,14 +41,14 @@ public class GetConfig implements RestReadView<ProjectResource> {
@Inject @Inject
public GetConfig( public GetConfig(
@EnableSignedPush boolean serverEnableSignedPush, @EnableSignedPush boolean serverEnableSignedPush,
TransferConfig config, TransferConfig transferConfig,
DynamicMap<ProjectConfigEntry> pluginConfigEntries, DynamicMap<ProjectConfigEntry> pluginConfigEntries,
PluginConfigFactory cfgFactory, PluginConfigFactory cfgFactory,
AllProjectsName allProjects, AllProjectsName allProjects,
UiActions uiActions, UiActions uiActions,
DynamicMap<RestView<ProjectResource>> views) { DynamicMap<RestView<ProjectResource>> views) {
this.serverEnableSignedPush = serverEnableSignedPush; this.serverEnableSignedPush = serverEnableSignedPush;
this.config = config; this.transferConfig = transferConfig;
this.pluginConfigEntries = pluginConfigEntries; this.pluginConfigEntries = pluginConfigEntries;
this.allProjects = allProjects; this.allProjects = allProjects;
this.cfgFactory = cfgFactory; this.cfgFactory = cfgFactory;
@@ -62,7 +62,7 @@ public class GetConfig implements RestReadView<ProjectResource> {
serverEnableSignedPush, serverEnableSignedPush,
resource.getProjectState(), resource.getProjectState(),
resource.getUser(), resource.getUser(),
config, transferConfig,
pluginConfigEntries, pluginConfigEntries,
cfgFactory, cfgFactory,
allProjects, allProjects,

View File

@@ -71,7 +71,7 @@ public class PutConfig implements RestModifyView<ProjectResource, ConfigInput> {
private final Provider<MetaDataUpdate.User> metaDataUpdateFactory; private final Provider<MetaDataUpdate.User> metaDataUpdateFactory;
private final ProjectCache projectCache; private final ProjectCache projectCache;
private final ProjectState.Factory projectStateFactory; private final ProjectState.Factory projectStateFactory;
private final TransferConfig config; private final TransferConfig transferConfig;
private final DynamicMap<ProjectConfigEntry> pluginConfigEntries; private final DynamicMap<ProjectConfigEntry> pluginConfigEntries;
private final PluginConfigFactory cfgFactory; private final PluginConfigFactory cfgFactory;
private final AllProjectsName allProjects; private final AllProjectsName allProjects;
@@ -86,7 +86,7 @@ public class PutConfig implements RestModifyView<ProjectResource, ConfigInput> {
Provider<MetaDataUpdate.User> metaDataUpdateFactory, Provider<MetaDataUpdate.User> metaDataUpdateFactory,
ProjectCache projectCache, ProjectCache projectCache,
ProjectState.Factory projectStateFactory, ProjectState.Factory projectStateFactory,
TransferConfig config, TransferConfig transferConfig,
DynamicMap<ProjectConfigEntry> pluginConfigEntries, DynamicMap<ProjectConfigEntry> pluginConfigEntries,
PluginConfigFactory cfgFactory, PluginConfigFactory cfgFactory,
AllProjectsName allProjects, AllProjectsName allProjects,
@@ -98,7 +98,7 @@ public class PutConfig implements RestModifyView<ProjectResource, ConfigInput> {
this.metaDataUpdateFactory = metaDataUpdateFactory; this.metaDataUpdateFactory = metaDataUpdateFactory;
this.projectCache = projectCache; this.projectCache = projectCache;
this.projectStateFactory = projectStateFactory; this.projectStateFactory = projectStateFactory;
this.config = config; this.transferConfig = transferConfig;
this.pluginConfigEntries = pluginConfigEntries; this.pluginConfigEntries = pluginConfigEntries;
this.cfgFactory = cfgFactory; this.cfgFactory = cfgFactory;
this.allProjects = allProjects; this.allProjects = allProjects;
@@ -168,12 +168,12 @@ public class PutConfig implements RestModifyView<ProjectResource, ConfigInput> {
throw new ResourceConflictException("Cannot update " + projectName); throw new ResourceConflictException("Cannot update " + projectName);
} }
ProjectState state = projectStateFactory.create(projectConfig); ProjectState state = projectStateFactory.create(ProjectConfig.read(md));
return new ConfigInfoImpl( return new ConfigInfoImpl(
serverEnableSignedPush, serverEnableSignedPush,
state, state,
user.get(), user.get(),
config, transferConfig,
pluginConfigEntries, pluginConfigEntries,
cfgFactory, cfgFactory,
allProjects, allProjects,

View File

@@ -44,6 +44,8 @@ import org.eclipse.jgit.lib.Config;
/** Provides access to the DataSource. */ /** Provides access to the DataSource. */
@Singleton @Singleton
public class DataSourceProvider implements Provider<DataSource>, LifecycleListener { public class DataSourceProvider implements Provider<DataSource>, LifecycleListener {
private static final String DATABASE_KEY = "database";
private final Config cfg; private final Config cfg;
private final MetricMaker metrics; private final MetricMaker metrics;
private final Context ctx; private final Context ctx;
@@ -93,7 +95,7 @@ public class DataSourceProvider implements Provider<DataSource>, LifecycleListen
} }
private DataSource open(Config cfg, Context context, DataSourceType dst) { private DataSource open(Config cfg, Context context, DataSourceType dst) {
ConfigSection dbs = new ConfigSection(cfg, "database"); ConfigSection dbs = new ConfigSection(cfg, DATABASE_KEY);
String driver = dbs.optional("driver"); String driver = dbs.optional("driver");
if (Strings.isNullOrEmpty(driver)) { if (Strings.isNullOrEmpty(driver)) {
driver = dst.getDriver(); driver = dst.getDriver();
@@ -112,41 +114,41 @@ public class DataSourceProvider implements Provider<DataSource>, LifecycleListen
if (context == Context.SINGLE_USER) { if (context == Context.SINGLE_USER) {
usePool = false; usePool = false;
} else { } else {
usePool = cfg.getBoolean("database", "connectionpool", dst.usePool()); usePool = cfg.getBoolean(DATABASE_KEY, "connectionpool", dst.usePool());
} }
if (usePool) { if (usePool) {
final BasicDataSource ds = new BasicDataSource(); final BasicDataSource lds = new BasicDataSource();
ds.setDriverClassName(driver); lds.setDriverClassName(driver);
ds.setUrl(url); lds.setUrl(url);
if (username != null && !username.isEmpty()) { if (username != null && !username.isEmpty()) {
ds.setUsername(username); lds.setUsername(username);
} }
if (password != null && !password.isEmpty()) { if (password != null && !password.isEmpty()) {
ds.setPassword(password); lds.setPassword(password);
} }
int poolLimit = threadSettingsConfig.getDatabasePoolLimit(); int poolLimit = threadSettingsConfig.getDatabasePoolLimit();
ds.setMaxActive(poolLimit); lds.setMaxActive(poolLimit);
ds.setMinIdle(cfg.getInt("database", "poolminidle", 4)); lds.setMinIdle(cfg.getInt(DATABASE_KEY, "poolminidle", 4));
ds.setMaxIdle(cfg.getInt("database", "poolmaxidle", Math.min(poolLimit, 16))); lds.setMaxIdle(cfg.getInt(DATABASE_KEY, "poolmaxidle", Math.min(poolLimit, 16)));
ds.setMaxWait( lds.setMaxWait(
ConfigUtil.getTimeUnit( ConfigUtil.getTimeUnit(
cfg, cfg,
"database", DATABASE_KEY,
null, null,
"poolmaxwait", "poolmaxwait",
MILLISECONDS.convert(30, SECONDS), MILLISECONDS.convert(30, SECONDS),
MILLISECONDS)); MILLISECONDS));
ds.setInitialSize(ds.getMinIdle()); lds.setInitialSize(lds.getMinIdle());
long evictIdleTimeMs = 1000L * 60; long evictIdleTimeMs = 1000L * 60;
ds.setMinEvictableIdleTimeMillis(evictIdleTimeMs); lds.setMinEvictableIdleTimeMillis(evictIdleTimeMs);
ds.setTimeBetweenEvictionRunsMillis(evictIdleTimeMs / 2); lds.setTimeBetweenEvictionRunsMillis(evictIdleTimeMs / 2);
ds.setTestOnBorrow(true); lds.setTestOnBorrow(true);
ds.setTestOnReturn(true); lds.setTestOnReturn(true);
ds.setValidationQuery(dst.getValidationQuery()); lds.setValidationQuery(dst.getValidationQuery());
ds.setValidationQueryTimeout(5); lds.setValidationQueryTimeout(5);
exportPoolMetrics(ds); exportPoolMetrics(lds);
return intercept(interceptor, ds); return intercept(interceptor, lds);
} }
// Don't use the connection pool. // Don't use the connection pool.
// //

View File

@@ -213,16 +213,6 @@ public class ChangeIT extends AbstractDaemonTest {
} }
} }
@Test
public void reflog() throws Exception {
// Tests are using DfsRepository which does not implement getReflogReader,
// so this will always fail.
// TODO: change this if/when DfsRepository#getReflogReader is implemented.
exception.expect(MethodNotAllowedException.class);
exception.expectMessage("reflog not supported");
gApi.projects().name(project.get()).branch("master").reflog();
}
@Test @Test
public void get() throws Exception { public void get() throws Exception {
PushOneCommit.Result r = createChange(); PushOneCommit.Result r = createChange();

View File

@@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.AtomicLongMap; import com.google.common.util.concurrent.AtomicLongMap;
import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.gerrit.acceptance.AbstractDaemonTest; import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.GitUtil; import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.NoHttpd; import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit; import com.google.gerrit.acceptance.PushOneCommit;
@@ -410,6 +411,104 @@ public class ProjectIT extends AbstractDaemonTest {
ImmutableMap.of(project.get(), 1L, middle.get(), 1L, leave.get(), 1L)); ImmutableMap.of(project.get(), 1L, middle.get(), 1L, leave.get(), 1L));
} }
@Test
public void maxObjectSizeIsNotSetByDefault() throws Exception {
ConfigInfo info = getConfig();
assertThat(info.maxObjectSizeLimit.value).isNull();
assertThat(info.maxObjectSizeLimit.configuredValue).isNull();
assertThat(info.maxObjectSizeLimit.inheritedValue).isNull();
}
@Test
public void maxObjectSizeCanBeSetAndCleared() throws Exception {
// Set a value
ConfigInput input = new ConfigInput();
input.maxObjectSizeLimit = "100k";
ConfigInfo info = setConfig(input);
assertThat(info.maxObjectSizeLimit.value).isEqualTo("100k");
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k");
assertThat(info.maxObjectSizeLimit.inheritedValue).isNull();
// Clear the value
input.maxObjectSizeLimit = "0";
info = setConfig(input);
assertThat(info.maxObjectSizeLimit.value).isNull();
assertThat(info.maxObjectSizeLimit.configuredValue).isNull();
assertThat(info.maxObjectSizeLimit.inheritedValue).isNull();
}
@Test
public void maxObjectSizeIsNotInheritedFromParentProject() throws Exception {
Project.NameKey child = createProject(name("child"), project);
ConfigInput input = new ConfigInput();
input.maxObjectSizeLimit = "100k";
ConfigInfo info = setConfig(input);
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k");
assertThat(info.maxObjectSizeLimit.inheritedValue).isNull();
info = getConfig(child);
assertThat(info.maxObjectSizeLimit.value).isNull();
assertThat(info.maxObjectSizeLimit.configuredValue).isNull();
assertThat(info.maxObjectSizeLimit.inheritedValue).isNull();
}
@Test
@GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k")
public void maxObjectSizeIsInheritedFromGlobalConfig() throws Exception {
ConfigInfo info = getConfig();
assertThat(info.maxObjectSizeLimit.value).isEqualTo("200k");
assertThat(info.maxObjectSizeLimit.configuredValue).isNull();
assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k");
}
@Test
@GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k")
public void maxObjectSizeOverridesGlobalConfigWhenLower() throws Exception {
ConfigInput input = new ConfigInput();
input.maxObjectSizeLimit = "100k";
ConfigInfo info = setConfig(input);
assertThat(info.maxObjectSizeLimit.value).isEqualTo("100k");
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k");
assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k");
}
@Test
@GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k")
public void maxObjectSizeDoesNotOverrideGlobalConfigWhenHigher() throws Exception {
ConfigInput input = new ConfigInput();
input.maxObjectSizeLimit = "300k";
ConfigInfo info = setConfig(input);
assertThat(info.maxObjectSizeLimit.value).isEqualTo("200k");
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("300k");
assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k");
}
@Test
public void invalidMaxObjectSizeIsRejected() throws Exception {
ConfigInput input = new ConfigInput();
input.maxObjectSizeLimit = "100 foo";
exception.expect(ResourceConflictException.class);
exception.expectMessage("100 foo");
setConfig(input);
}
private ConfigInfo setConfig(Project.NameKey name, ConfigInput input) throws Exception {
return gApi.projects().name(name.get()).config(input);
}
private ConfigInfo setConfig(ConfigInput input) throws Exception {
return setConfig(project, input);
}
private ConfigInfo getConfig(Project.NameKey name) throws Exception {
return gApi.projects().name(name.get()).config();
}
private ConfigInfo getConfig() throws Exception {
return getConfig(project);
}
private ConfigInput createTestConfigInput() { private ConfigInput createTestConfigInput() {
ConfigInput input = new ConfigInput(); ConfigInput input = new ConfigInput();
input.description = "some description"; input.description = "some description";

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package com.google.gerrit.acceptance.server.notedb; package com.google.gerrit.acceptance.server.project;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.TruthJUnit.assume; import static com.google.common.truth.TruthJUnit.assume;
@@ -21,8 +21,12 @@ import static com.google.gerrit.reviewdb.client.RefNames.changeMetaRef;
import com.google.gerrit.acceptance.AbstractDaemonTest; import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit; import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.UseLocalDisk; import com.google.gerrit.acceptance.UseLocalDisk;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.projects.BranchApi;
import com.google.gerrit.extensions.api.projects.ReflogEntryInfo;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import java.io.File; import java.io.File;
import java.util.List;
import org.eclipse.jgit.lib.ReflogEntry; import org.eclipse.jgit.lib.ReflogEntry;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import org.junit.Test; import org.junit.Test;
@@ -48,4 +52,26 @@ public class ReflogIT extends AbstractDaemonTest {
assertThat(last.getComment()).isEqualTo("restapi.change.PutTopic"); assertThat(last.getComment()).isEqualTo("restapi.change.PutTopic");
} }
} }
@Test
public void reflogUpdatedBySubmittingChange() throws Exception {
BranchApi branchApi = gApi.projects().name(project.get()).branch("master");
List<ReflogEntryInfo> reflog = branchApi.reflog();
assertThat(reflog).isNotEmpty();
// Current number of entries in the reflog
int refLogLen = reflog.size();
// Create and submit a change
PushOneCommit.Result r = createChange();
String changeId = r.getChangeId();
String revision = r.getCommit().name();
ReviewInput in = ReviewInput.approve();
gApi.changes().id(changeId).revision(revision).review(in);
gApi.changes().id(changeId).revision(revision).submit();
// Submitting the change causes a new entry in the reflog
reflog = branchApi.reflog();
assertThat(reflog).hasSize(refLogLen + 1);
}
} }