Merge branch 'stable-3.1' into stable-3.2

* stable-3.1:
  Add metric monitoring Java deadlocks
  Fix wrong status returned when auth backend couldn't be reached
  Add debug logs for copying approvals to new patch sets
  Revert "ApprovalCopier: Add debug logging of logic in canCopy"
  ChangeKindCacheImpl: Add debug logging of detected change kind
  ApprovalCopier: Add debug logging of logic in canCopy
  Documentation: Fix plugins install REST API & curl example
  Fix minor typo in WORKSPACE
  Fix `parent` in `gr-change-metadata` when switching patchsets
  Update git submodules
  Update git submodules
  Revert "Fix edit diff url"
  Upgrade testcontainers to 1.14.2
  Update git submodules
  Use UUID rather than group_id for links in gr-admin-group-list
  Fix Postgresql JDBC driver leaking memory

Change-Id: Ic01d45b4002889d2abb1e4813672052d5ab120ed
This commit is contained in:
David Pursehouse
2020-05-21 14:28:11 +09:00
15 changed files with 123 additions and 34 deletions

View File

@@ -54,6 +54,8 @@ objects needing finalization.
* `proc/jvm/thread/num_daemon_live`: Current live daemon threads count. * `proc/jvm/thread/num_daemon_live`: Current live daemon threads count.
* `proc/jvm/thread/num_peak_live`: Peak live thread count since the Java virtual machine started or peak was reset. * `proc/jvm/thread/num_peak_live`: Peak live thread count since the Java virtual machine started or peak was reset.
* `proc/jvm/thread/num_total_started`: Total number of threads created and also started since the Java virtual machine started. * `proc/jvm/thread/num_total_started`: Total number of threads created and also started since the Java virtual machine started.
* `proc/jvm/thread/num_deadlocked_threads`: Number of threads that are deadlocked waiting for object monitors or ownable synchronizers.
If deadlocks waiting for ownable synchronizers can be monitored depends on the capabilities of the used JVM.
=== Caches === Caches

View File

@@ -246,7 +246,7 @@ List all plugins that match substring `project`:
[[install-plugin]] [[install-plugin]]
=== Install Plugin === Install Plugin
-- --
'PUT /plugins/link:#plugin-id[\{plugin-id\}]' 'PUT /plugins/link:#plugin-id[\{plugin-id\}].jar'
-- --
Installs a new plugin on the Gerrit server. If a plugin with the Installs a new plugin on the Gerrit server. If a plugin with the
@@ -260,7 +260,7 @@ a link:#plugin-input[PluginInput] entity.
.Request .Request
---- ----
PUT /plugins/delete-project HTTP/1.0 PUT /plugins/delete-project.jar HTTP/1.0
Content-Type: application/json; charset=UTF-8 Content-Type: application/json; charset=UTF-8
{ {
@@ -272,7 +272,7 @@ To provide the plugin jar as binary data in the request body the
following curl command can be used: following curl command can be used:
---- ----
curl --user admin:TNNuLkWsIV8w -X PUT --data-binary @delete-project-2.8.jar 'http://gerrit:8080/a/plugins/delete-project' curl --user admin:TNNuLkWsIV8w -X PUT -H "Content-Type:application/octet-stream" --data-binary @delete-project.jar 'http://gerrit:8080/a/plugins/delete-project.jar'
---- ----
As response a link:#plugin-info[PluginInfo] entity is returned that As response a link:#plugin-info[PluginInfo] entity is returned that
@@ -282,12 +282,15 @@ describes the plugin.
---- ----
HTTP/1.1 201 Created HTTP/1.1 201 Created
Content-Disposition: attachment Content-Disposition: attachment
Content-Type: application/json; charset=UTF-8 Content-Type: application/json;charset=utf-8
Content-Length: 150
)]}' )]}'
{ {
"id": "delete-project", "id": "delete-project",
"version": "2.8" "version": "v2.16-221-g35bb8bbac4",
"index_url": "plugins/delete-project/",
"filename": "delete-project.jar"
} }
---- ----

View File

@@ -267,7 +267,7 @@ maven_jar(
CAFFEINE_GUAVA_SHA256 = "3a66ee3ec70971dee0bae6e56bda7b8742bc4bedd7489161bfbbaaf7137d89e1" CAFFEINE_GUAVA_SHA256 = "3a66ee3ec70971dee0bae6e56bda7b8742bc4bedd7489161bfbbaaf7137d89e1"
# TODO(davido): Rename guava.jar to caffeine-guava.jar on fetch to prevent potential # TODO(davido): Rename guava.jar to caffeine-guava.jar on fetch to prevent potential
# naming collision between caffeine guava adapater and guava library itself. # naming collision between caffeine guava adapter and guava library itself.
# Remove this renaming procedure, once this upstream issue is fixed: # Remove this renaming procedure, once this upstream issue is fixed:
# https://github.com/ben-manes/caffeine/issues/364. # https://github.com/ben-manes/caffeine/issues/364.
http_file( http_file(

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.httpd; package com.google.gerrit.httpd;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
@@ -33,6 +34,7 @@ import com.google.gerrit.server.account.AuthRequest;
import com.google.gerrit.server.account.AuthResult; import com.google.gerrit.server.account.AuthResult;
import com.google.gerrit.server.account.AuthenticationFailedException; import com.google.gerrit.server.account.AuthenticationFailedException;
import com.google.gerrit.server.account.externalids.PasswordVerifier; import com.google.gerrit.server.account.externalids.PasswordVerifier;
import com.google.gerrit.server.auth.AuthenticationUnavailableException;
import com.google.gerrit.server.auth.NoSuchUserException; import com.google.gerrit.server.auth.NoSuchUserException;
import com.google.gerrit.server.config.AuthConfig; import com.google.gerrit.server.config.AuthConfig;
import com.google.inject.Inject; import com.google.inject.Inject;
@@ -170,6 +172,10 @@ class ProjectBasicAuthFilter implements Filter {
logger.atWarning().log(authenticationFailedMsg(username, req) + ": %s", e.getMessage()); logger.atWarning().log(authenticationFailedMsg(username, req) + ": %s", e.getMessage());
rsp.sendError(SC_UNAUTHORIZED); rsp.sendError(SC_UNAUTHORIZED);
return false; return false;
} catch (AuthenticationUnavailableException e) {
logger.atSevere().withCause(e).log("could not reach authentication backend");
rsp.sendError(SC_SERVICE_UNAVAILABLE);
return false;
} catch (AccountException e) { } catch (AccountException e) {
logger.atWarning().withCause(e).log(authenticationFailedMsg(username, req)); logger.atWarning().withCause(e).log(authenticationFailedMsg(username, req));
rsp.sendError(SC_UNAUTHORIZED); rsp.sendError(SC_UNAUTHORIZED);

View File

@@ -234,5 +234,36 @@ public class ProcMetricModule extends MetricModule {
.setGauge() .setGauge()
.setUnit("threads"), .setUnit("threads"),
thread::getTotalStartedThreadCount); thread::getTotalStartedThreadCount);
if (thread.isSynchronizerUsageSupported()) {
metrics.newCallbackMetric(
"proc/jvm/thread/num_deadlocked_threads",
Integer.class,
new Description(
"number of threads that are deadlocked waiting for object monitors or ownable synchronizers")
.setGauge()
.setUnit("threads"),
() -> {
long[] deadlocked = thread.findDeadlockedThreads();
if (deadlocked == null) {
return 0;
}
return deadlocked.length;
});
} else {
metrics.newCallbackMetric(
"proc/jvm/thread/num_deadlocked_threads",
Integer.class,
new Description(
"number of threads that are deadlocked waiting to acquire object monitors")
.setGauge()
.setUnit("threads"),
() -> {
long[] deadlocked = thread.findMonitorDeadlockedThreads();
if (deadlocked == null) {
return 0;
}
return deadlocked.length;
});
}
} }
} }

View File

@@ -344,10 +344,12 @@ public class ChangeKindCacheImpl implements ChangeKindCache {
ObjectId next) { ObjectId next) {
try { try {
Key key = Key.create(prior, next, useRecursiveMerge); Key key = Key.create(prior, next, useRecursiveMerge);
return cache.get(key, new Loader(key, repoManager, project, rw, repoConfig)); ChangeKind kind = cache.get(key, new Loader(key, repoManager, project, rw, repoConfig));
logger.atFine().log("Change kind of new patch set %s in %s: %s", next.name(), project, kind);
return kind;
} catch (ExecutionException e) { } catch (ExecutionException e) {
logger.atWarning().withCause(e).log( logger.atWarning().withCause(e).log(
"Cannot check trivial rebase of new patch set %s in %s", next.name(), project); "Cannot check change kind of new patch set %s in %s", next.name(), project);
return ChangeKind.REWORK; return ChangeKind.REWORK;
} }
} }
@@ -400,6 +402,8 @@ public class ChangeKindCacheImpl implements ChangeKindCache {
patch.number(), change.getId()); patch.number(), change.getId());
} }
} }
logger.atFine().log(
"Change kind for patchSet %s of change %s: %s", patch.number(), change.getId(), kind);
return kind; return kind;
} }
@@ -426,6 +430,8 @@ public class ChangeKindCacheImpl implements ChangeKindCache {
patch.number(), change.getChangeId()); patch.number(), change.getChangeId());
} }
} }
logger.atFine().log(
"Change kind for patchSet %s of change %s: %s", patch.number(), change.getChangeId(), kind);
return kind; return kind;
} }
} }

View File

@@ -123,8 +123,13 @@ class GrAdminGroupList extends mixinBehaviors( [
} }
} }
/**
* Generates groups link (/admin/groups/<uuid>)
*
* @param {string} id
*/
_computeGroupUrl(id) { _computeGroupUrl(id) {
return GerritNav.getUrlForGroup(id); return GerritNav.getUrlForGroup(decodeURIComponent(id));
} }
_getCreateGroupCapability() { _getCreateGroupCapability() {

View File

@@ -48,7 +48,7 @@ export const htmlTemplate = html`
<template is="dom-repeat" items="[[_shownGroups]]"> <template is="dom-repeat" items="[[_shownGroups]]">
<tr class="table"> <tr class="table">
<td class="name"> <td class="name">
<a href$="[[_computeGroupUrl(item.group_id)]]">[[item.name]]</a> <a href$="[[_computeGroupUrl(item.id)]]">[[item.name]]</a>
</td> </td>
<td class="description">[[item.description]]</td> <td class="description">[[item.description]]</td>
<td class="visibleToAll">[[_visibleToAll(item)]]</td> <td class="visibleToAll">[[_visibleToAll(item)]]</td>

View File

@@ -35,6 +35,7 @@ limitations under the License.
<script type="module"> <script type="module">
import '../../../test/common-test-setup.js'; import '../../../test/common-test-setup.js';
import './gr-admin-group-list.js'; import './gr-admin-group-list.js';
import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
let counter = 0; let counter = 0;
const groupGenerator = () => { const groupGenerator = () => {
return { return {
@@ -66,6 +67,30 @@ suite('gr-admin-group-list tests', () => {
sandbox.restore(); sandbox.restore();
}); });
test('_computeGroupUrl', () => {
let urlStub = sandbox.stub(GerritNav, 'getUrlForGroup',
() => '/admin/groups/e2cd66f88a2db4d391ac068a92d987effbe872f5');
let group = {
id: 'e2cd66f88a2db4d391ac068a92d987effbe872f5',
};
assert.equal(element._computeGroupUrl(group),
'/admin/groups/e2cd66f88a2db4d391ac068a92d987effbe872f5');
urlStub.restore();
urlStub = sandbox.stub(GerritNav, 'getUrlForGroup',
() => '/admin/groups/user/test');
group = {
id: 'user%2Ftest',
};
assert.equal(element._computeGroupUrl(group),
'/admin/groups/user/test');
urlStub.restore();
});
suite('list with groups', () => { suite('list with groups', () => {
setup(done => { setup(done => {
groups = _.times(26, groupGenerator); groups = _.times(26, groupGenerator);

View File

@@ -152,7 +152,7 @@ class GrChangeMetadata extends mixinBehaviors( [
_currentParents: { _currentParents: {
type: Array, type: Array,
computed: '_computeParents(change)', computed: '_computeParents(revision)',
}, },
/** @type {?} */ /** @type {?} */
@@ -494,13 +494,11 @@ class GrChangeMetadata extends mixinBehaviors( [
return null; return null;
} }
_computeParents(change) { _computeParents(revision) {
if (!change || !change.current_revision || if (!revision || !revision.commit) {
!change.revisions[change.current_revision] ||
!change.revisions[change.current_revision].commit) {
return undefined; return undefined;
} }
return change.revisions[change.current_revision].commit.parents; return revision.commit.parents;
} }
_computeParentsLabel(parents) { _computeParentsLabel(parents) {

View File

@@ -426,14 +426,20 @@ suite('gr-change-metadata tests', () => {
}); });
test('_computeParents', () => { test('_computeParents', () => {
const parents = [{commit: '123', subject: 'abc'}]; const revision = {commit: {parents: [{commit: '123', subject: 'abc'}]}};
assert.isUndefined(element._computeParents( assert.isUndefined(element._computeParents({}));
{revisions: {456: {commit: {parents}}}})); assert.equal(element._computeParents(revision), revision.commit.parents);
assert.isUndefined(element._computeParents( });
{current_revision: '789', revisions: {456: {commit: {parents}}}}));
assert.equal(element._computeParents( test('_currentParents', () => {
{current_revision: '456', revisions: {456: {commit: {parents}}}}), element.revision = {
parents); commit: {parents: [{commit: '123', subject: 'abc'}]},
};
assert.equal(element._currentParents[0].commit, '123');
element.revision = {
commit: {parents: [{commit: '12345', subject: 'abc'}]},
};
assert.equal(element._currentParents[0].commit, '12345');
}); });
test('_computeParentsLabel', () => { test('_computeParentsLabel', () => {

View File

@@ -646,7 +646,8 @@ class GrDiffView extends mixinBehaviors( [
_goToEditFile() { _goToEditFile() {
// TODO(taoalpha): add a shortcut for editing // TODO(taoalpha): add a shortcut for editing
const editUrl = GerritNav.getEditUrlForDiff(this._change, this._path); const editUrl = GerritNav.getEditUrlForDiff(
this._change, this._path, this._patchRange.patchNum);
return GerritNav.navigateToRelativeUrl(editUrl); return GerritNav.navigateToRelativeUrl(editUrl);
} }

View File

@@ -403,7 +403,6 @@ suite('gr-diff-view tests', () => {
}; };
element._change = { element._change = {
_number: 42, _number: 42,
project: 'gerrit',
status: 'NEW', status: 'NEW',
revisions: { revisions: {
a: {_number: 1, commit: {parents: []}}, a: {_number: 1, commit: {parents: []}},
@@ -417,8 +416,6 @@ suite('gr-diff-view tests', () => {
assert.isTrue(!!editBtn); assert.isTrue(!!editBtn);
MockInteractions.tap(editBtn); MockInteractions.tap(editBtn);
assert.isTrue(redirectStub.called); assert.isTrue(redirectStub.called);
assert.isTrue(redirectStub.lastCall.calledWithExactly(
GerritNav.getEditUrlForDiff(element._change, element._path)));
done(); done();
}); });
}); });

View File

@@ -95,21 +95,30 @@ suite('gr-group-list tests', () => {
}); });
test('_computeGroupPath', () => { test('_computeGroupPath', () => {
sandbox.stub(GerritNav, 'getUrlForGroup', let urlStub = sandbox.stub(GerritNav, 'getUrlForGroup',
() => '/admin/groups/e2cd66f88a2db4d391ac068a92d987effbe872f5'); () => '/admin/groups/e2cd66f88a2db4d391ac068a92d987effbe872f5');
let group = { let group = {
id: 'e2cd66f88a2db4d391ac068a92d987effbe872f5', id: 'e2cd66f88a2db4d391ac068a92d987effbe872f5',
}; };
assert.equal(element._computeGroupPath(group), assert.equal(element._computeGroupPath(group),
'/admin/groups/e2cd66f88a2db4d391ac068a92d987effbe872f5'); '/admin/groups/e2cd66f88a2db4d391ac068a92d987effbe872f5');
group = { group = {
name: 'admin', name: 'admin',
}; };
assert.isUndefined(element._computeGroupPath(group)); assert.isUndefined(element._computeGroupPath(group));
urlStub.restore();
urlStub = sandbox.stub(GerritNav, 'getUrlForGroup',
() => '/admin/groups/user/test');
group = {
id: 'user%2Ftest',
};
assert.equal(element._computeGroupPath(group),
'/admin/groups/user/test');
}); });
}); });
</script> </script>

View File

@@ -120,18 +120,18 @@ def declare_nongoogle_deps():
sha1 = "dc13ae4faca6df981fc7aeb5a522d9db446d5d50", sha1 = "dc13ae4faca6df981fc7aeb5a522d9db446d5d50",
) )
TESTCONTAINERS_VERSION = "1.14.1" TESTCONTAINERS_VERSION = "1.14.2"
maven_jar( maven_jar(
name = "testcontainers", name = "testcontainers",
artifact = "org.testcontainers:testcontainers:" + TESTCONTAINERS_VERSION, artifact = "org.testcontainers:testcontainers:" + TESTCONTAINERS_VERSION,
sha1 = "defd04ff6ffc93e1ff988024048e8ba5bd298df3", sha1 = "d74bc045fb5f30988b0adff20244412972a9f564",
) )
maven_jar( maven_jar(
name = "testcontainers-elasticsearch", name = "testcontainers-elasticsearch",
artifact = "org.testcontainers:elasticsearch:" + TESTCONTAINERS_VERSION, artifact = "org.testcontainers:elasticsearch:" + TESTCONTAINERS_VERSION,
sha1 = "d682965bbf1334ef40720b4ad2eda2c12bf0b440", sha1 = "66e1a6da0362beee83673b877c9c2e0536d6912c",
) )
maven_jar( maven_jar(