Skip to content

Commit 78880e8

Browse files
committed
HADOOP-19712. S3A: Deadlock in EvaluatingStatisticsMap.entryset()
Add a test with a larger set of entries (env vars) and more assertions. Due diligence.
1 parent bfb91e8 commit 78880e8

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/statistics/impl/EvaluatingStatisticsMap.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.LinkedHashSet;
2525
import java.util.List;
2626
import java.util.Map;
27+
import java.util.Objects;
2728
import java.util.Set;
2829
import java.util.concurrent.ConcurrentHashMap;
2930
import java.util.function.BiConsumer;
@@ -190,7 +191,7 @@ public void forEach(final BiConsumer<? super String, ? super E> action) {
190191
*/
191192
private static final class EntryImpl<E> implements Entry<String, E> {
192193

193-
private String key;
194+
private final String key;
194195

195196
private E value;
196197

@@ -214,6 +215,18 @@ public E setValue(final E val) {
214215
this.value = val;
215216
return val;
216217
}
218+
219+
@Override
220+
public boolean equals(final Object o) {
221+
if (!(o instanceof Entry)) {return false;}
222+
Entry<String, ?> entry = (Entry<String, ?>) o;
223+
return Objects.equals(key, entry.getKey()) && Objects.equals(value, entry.getValue());
224+
}
225+
226+
@Override
227+
public int hashCode() {
228+
return Objects.hashCode(key);
229+
}
217230
}
218231

219232
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.hadoop.fs.statistics.impl;
20+
21+
import java.util.Map;
22+
23+
import org.assertj.core.api.Assertions;
24+
import org.junit.jupiter.api.Test;
25+
26+
import org.apache.hadoop.test.AbstractHadoopTestBase;
27+
28+
import static org.assertj.core.api.Assertions.assertThat;
29+
30+
public class TestEvaluatingStatisticsMap extends AbstractHadoopTestBase {
31+
32+
33+
@Test
34+
public void testEvaluatingStatisticsMap() {
35+
EvaluatingStatisticsMap<String> map = new EvaluatingStatisticsMap<>();
36+
37+
Assertions.assertThat(map).isEmpty();
38+
Assertions.assertThat(map.keySet()).isEmpty();
39+
Assertions.assertThat(map.values()).isEmpty();
40+
Assertions.assertThat(map.entrySet()).isEmpty();
41+
42+
// fill the map with the environment vars
43+
final Map<String, String> env = System.getenv();
44+
env.forEach((k, v) -> map.addFunction(k, any -> v));
45+
46+
// verify the keys match
47+
assertThat(map.keySet())
48+
.describedAs("keys")
49+
.containsExactlyInAnyOrderElementsOf(env.keySet());
50+
51+
// and that the values do
52+
assertThat(map.values())
53+
.describedAs("Evaluated values")
54+
.containsExactlyInAnyOrderElementsOf(env.values());
55+
56+
// now assert that this holds for the entryset.
57+
env.forEach((k, v) ->
58+
assertThat(map.get(k))
59+
.describedAs("looked up key %s", k)
60+
.isNotNull()
61+
.isEqualTo(v));
62+
63+
map.forEach((k, v) ->
64+
assertThat(env.get(k))
65+
.describedAs("env var %s", k)
66+
.isNotNull()
67+
.isEqualTo(v));
68+
69+
70+
}
71+
}

0 commit comments

Comments
 (0)