Skip to content

Commit febf22c

Browse files
authored
refactor custom metadata integration test (#82714)
currently, custom metadata integration test combines 3-4 test cases in a single test method. This change split the test into separate scenarios and removes code duplication.
1 parent 40bb62e commit febf22c

File tree

3 files changed

+262
-401
lines changed

3 files changed

+262
-401
lines changed
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
package org.elasticsearch.snapshots;
9+
10+
import org.elasticsearch.Version;
11+
import org.elasticsearch.cluster.NamedDiff;
12+
import org.elasticsearch.cluster.metadata.Metadata;
13+
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
14+
import org.elasticsearch.common.io.stream.Writeable;
15+
import org.elasticsearch.core.CheckedFunction;
16+
import org.elasticsearch.plugins.Plugin;
17+
import org.elasticsearch.repositories.RepositoryMissingException;
18+
import org.elasticsearch.test.TestCustomMetadata;
19+
import org.elasticsearch.xcontent.NamedXContentRegistry;
20+
import org.elasticsearch.xcontent.ParseField;
21+
import org.elasticsearch.xcontent.XContentParser;
22+
23+
import java.io.IOException;
24+
import java.util.ArrayList;
25+
import java.util.Collection;
26+
import java.util.Collections;
27+
import java.util.EnumSet;
28+
import java.util.List;
29+
import java.util.Map;
30+
import java.util.function.Function;
31+
32+
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
33+
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertRequestBuilderThrows;
34+
import static org.hamcrest.Matchers.equalTo;
35+
import static org.hamcrest.Matchers.nullValue;
36+
37+
public class CustomMetadataContextIT extends AbstractSnapshotIntegTestCase {
38+
39+
@Override
40+
protected Collection<Class<? extends Plugin>> nodePlugins() {
41+
return Collections.singletonList(TestCustomMetadataPlugin.class);
42+
}
43+
44+
public void testShouldNotRestoreRepositoryMetadata() {
45+
var repoPath = randomRepoPath();
46+
47+
logger.info("create repository");
48+
createRepository("test-repo-1", "fs", repoPath);
49+
50+
logger.info("create snapshot");
51+
createFullSnapshot("test-repo-1", "test-snap");
52+
assertThat(getSnapshot("test-repo-1", "test-snap").state(), equalTo(SnapshotState.SUCCESS));
53+
54+
logger.info("delete repository");
55+
assertAcked(clusterAdmin().prepareDeleteRepository("test-repo-1"));
56+
57+
logger.info("create another repository");
58+
createRepository("test-repo-2", "fs", repoPath);
59+
60+
logger.info("restore snapshot");
61+
clusterAdmin().prepareRestoreSnapshot("test-repo-2", "test-snap")
62+
.setRestoreGlobalState(true)
63+
.setIndices("-*")
64+
.setWaitForCompletion(true)
65+
.execute()
66+
.actionGet();
67+
68+
logger.info("make sure old repository wasn't restored");
69+
assertRequestBuilderThrows(clusterAdmin().prepareGetRepositories("test-repo-1"), RepositoryMissingException.class);
70+
assertThat(clusterAdmin().prepareGetRepositories("test-repo-2").get().repositories().size(), equalTo(1));
71+
}
72+
73+
public void testShouldRestoreOnlySnapshotMetadata() throws Exception {
74+
var repoPath = randomRepoPath();
75+
76+
logger.info("create repository");
77+
createRepository("test-repo", "fs", repoPath);
78+
79+
logger.info("add custom persistent metadata");
80+
boolean isSnapshotMetadataSet = randomBoolean();
81+
updateClusterState(currentState -> currentState.copyAndUpdateMetadata(metadataBuilder -> {
82+
if (isSnapshotMetadataSet) {
83+
metadataBuilder.putCustom(SnapshotMetadata.TYPE, new SnapshotMetadata("before_snapshot_s"));
84+
}
85+
metadataBuilder.putCustom(ApiMetadata.TYPE, new ApiMetadata("before_snapshot_ns"));
86+
}));
87+
88+
logger.info("create snapshot");
89+
createFullSnapshot("test-repo", "test-snapshot");
90+
assertThat(getSnapshot("test-repo", "test-snapshot").state(), equalTo(SnapshotState.SUCCESS));
91+
92+
logger.info("update custom persistent metadata");
93+
updateClusterState(currentState -> currentState.copyAndUpdateMetadata(metadataBuilder -> {
94+
if (isSnapshotMetadataSet == false || randomBoolean()) {
95+
metadataBuilder.putCustom(SnapshotMetadata.TYPE, new SnapshotMetadata("after_snapshot_s"));
96+
} else {
97+
metadataBuilder.removeCustom(SnapshotMetadata.TYPE);
98+
}
99+
metadataBuilder.putCustom(ApiMetadata.TYPE, new ApiMetadata("after_snapshot_ns"));
100+
}));
101+
102+
logger.info("restore snapshot");
103+
clusterAdmin().prepareRestoreSnapshot("test-repo", "test-snapshot")
104+
.setRestoreGlobalState(true)
105+
.setIndices("-*")
106+
.setWaitForCompletion(true)
107+
.execute()
108+
.actionGet();
109+
110+
var metadata = clusterAdmin().prepareState().get().getState().getMetadata();
111+
logger.info("check that custom persistent metadata [{}] is correctly restored", metadata);
112+
if (isSnapshotMetadataSet) {
113+
assertThat(metadata.<SnapshotMetadata>custom(SnapshotMetadata.TYPE).getData(), equalTo("before_snapshot_s"));
114+
} else {
115+
assertThat(metadata.<SnapshotMetadata>custom(SnapshotMetadata.TYPE), nullValue());
116+
}
117+
assertThat(metadata.<ApiMetadata>custom(ApiMetadata.TYPE).getData(), equalTo("after_snapshot_ns"));
118+
}
119+
120+
public void testShouldKeepGatewayMetadataAfterRestart() throws Exception {
121+
logger.info("add custom gateway metadata");
122+
updateClusterState(currentState -> currentState.copyAndUpdateMetadata(metadataBuilder -> {
123+
metadataBuilder.putCustom(GatewayMetadata.TYPE, new GatewayMetadata("before_restart_s_gw"));
124+
metadataBuilder.putCustom(ApiMetadata.TYPE, new ApiMetadata("before_restart_ns"));
125+
}));
126+
127+
logger.info("restart all nodes");
128+
internalCluster().fullRestart();
129+
ensureYellow();
130+
131+
var metadata = clusterAdmin().prepareState().get().getState().getMetadata();
132+
logger.info("check that gateway custom metadata [{}] survived full cluster restart", metadata);
133+
assertThat(metadata.<GatewayMetadata>custom(GatewayMetadata.TYPE).getData(), equalTo("before_restart_s_gw"));
134+
assertThat(metadata.<ApiMetadata>custom(ApiMetadata.TYPE), nullValue());
135+
}
136+
137+
public void testShouldExposeApiMetadata() throws Exception {
138+
logger.info("add custom api metadata");
139+
updateClusterState(currentState -> currentState.copyAndUpdateMetadata(metadataBuilder -> {
140+
metadataBuilder.putCustom(ApiMetadata.TYPE, new ApiMetadata("before_restart_s_gw"));
141+
metadataBuilder.putCustom(NonApiMetadata.TYPE, new NonApiMetadata("before_restart_ns"));
142+
}));
143+
144+
var metadata = clusterAdmin().prepareState().get().getState().getMetadata();
145+
logger.info("check that api custom metadata [{}] is visible via api", metadata);
146+
assertThat(metadata.<ApiMetadata>custom(ApiMetadata.TYPE).getData(), equalTo("before_restart_s_gw"));
147+
assertThat(metadata.<NonApiMetadata>custom(NonApiMetadata.TYPE), nullValue());
148+
}
149+
150+
public static class TestCustomMetadataPlugin extends Plugin {
151+
152+
private final List<NamedWriteableRegistry.Entry> namedWritables = new ArrayList<>();
153+
private final List<NamedXContentRegistry.Entry> namedXContents = new ArrayList<>();
154+
155+
public TestCustomMetadataPlugin() {
156+
registerBuiltinWritables();
157+
}
158+
159+
private <T extends Metadata.Custom> void registerMetadataCustom(
160+
String name,
161+
Writeable.Reader<T> reader,
162+
Writeable.Reader<NamedDiff<?>> diffReader,
163+
CheckedFunction<XContentParser, T, IOException> parser
164+
) {
165+
namedWritables.add(new NamedWriteableRegistry.Entry(Metadata.Custom.class, name, reader));
166+
namedWritables.add(new NamedWriteableRegistry.Entry(NamedDiff.class, name, diffReader));
167+
namedXContents.add(new NamedXContentRegistry.Entry(Metadata.Custom.class, new ParseField(name), parser));
168+
}
169+
170+
private void registerBuiltinWritables() {
171+
Map.<String, Function<String, TestCustomMetadata>>of(
172+
SnapshotMetadata.TYPE,
173+
SnapshotMetadata::new,
174+
GatewayMetadata.TYPE,
175+
GatewayMetadata::new,
176+
ApiMetadata.TYPE,
177+
ApiMetadata::new,
178+
NonApiMetadata.TYPE,
179+
NonApiMetadata::new
180+
)
181+
.forEach(
182+
(type, constructor) -> registerMetadataCustom(
183+
type,
184+
in -> TestCustomMetadata.readFrom(constructor, in),
185+
in -> TestCustomMetadata.readDiffFrom(type, in),
186+
parser -> TestCustomMetadata.fromXContent(constructor, parser)
187+
)
188+
);
189+
}
190+
191+
@Override
192+
public List<NamedWriteableRegistry.Entry> getNamedWriteables() {
193+
return namedWritables;
194+
}
195+
196+
@Override
197+
public List<NamedXContentRegistry.Entry> getNamedXContent() {
198+
return namedXContents;
199+
}
200+
}
201+
202+
private abstract static class ThisTestCustomMetadata extends TestCustomMetadata {
203+
private final String type;
204+
private final EnumSet<Metadata.XContentContext> context;
205+
206+
ThisTestCustomMetadata(String data, String type, EnumSet<Metadata.XContentContext> context) {
207+
super(data);
208+
this.type = type;
209+
this.context = context;
210+
}
211+
212+
@Override
213+
public String getWriteableName() {
214+
return type;
215+
}
216+
217+
@Override
218+
public Version getMinimalSupportedVersion() {
219+
return Version.CURRENT;
220+
}
221+
222+
@Override
223+
public EnumSet<Metadata.XContentContext> context() {
224+
return context;
225+
}
226+
}
227+
228+
private static class SnapshotMetadata extends ThisTestCustomMetadata {
229+
public static final String TYPE = "test_metadata_scope_snapshot";
230+
231+
SnapshotMetadata(String data) {
232+
super(data, TYPE, Metadata.API_AND_SNAPSHOT);
233+
}
234+
}
235+
236+
private static class GatewayMetadata extends ThisTestCustomMetadata {
237+
public static final String TYPE = "test_metadata_scope_gateway";
238+
239+
GatewayMetadata(String data) {
240+
super(data, TYPE, Metadata.API_AND_GATEWAY);
241+
}
242+
}
243+
244+
private static class ApiMetadata extends ThisTestCustomMetadata {
245+
public static final String TYPE = "test_metadata_scope_api";
246+
247+
ApiMetadata(String data) {
248+
super(data, TYPE, Metadata.API_ONLY);
249+
}
250+
}
251+
252+
private static class NonApiMetadata extends ThisTestCustomMetadata {
253+
public static final String TYPE = "test_metadata_scope_non_api";
254+
255+
NonApiMetadata(String data) {
256+
super(data, TYPE, EnumSet.of(Metadata.XContentContext.GATEWAY, Metadata.XContentContext.SNAPSHOT));
257+
}
258+
}
259+
}

0 commit comments

Comments
 (0)