Skip to content

Commit 7644c4c

Browse files
committed
unit tests
1 parent 224c101 commit 7644c4c

6 files changed

Lines changed: 129 additions & 11 deletions

File tree

graylog2-server/src/main/java/org/graylog2/contentpacks/model/entities/QueryEntity.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,21 @@ private Filter shallowMappedFilter(Map<EntityDescriptor, Object> nativeEntities)
154154
.map(filter -> {
155155
if (filter.type().matches(StreamFilter.NAME)) {
156156
final StreamFilter streamFilter = (StreamFilter) filter;
157-
final Stream stream = (Stream) resolveStreamEntityObject(streamFilter.streamId(), nativeEntities);
158-
if (Objects.isNull(stream)) {
157+
final Object object = resolveStreamEntityObject(streamFilter.streamId(), nativeEntities);
158+
if (object == null) {
159159
// Skip a dangling stream reference instead of aborting the whole content pack
160160
// installation. This mirrors the export side, which also drops unresolvable references.
161161
LOG.warn("Skipping unresolvable stream reference <{}> in query filter for query <{}> during content pack installation",
162162
streamFilter.streamId(), id());
163163
return null;
164+
} else if (object instanceof final Stream stream) {
165+
return streamFilter.toBuilder().streamId(stream.getId()).build();
166+
} else {
167+
// A non-null, non-Stream value indicates a corrupt entity map rather than a
168+
// missing reference, so abort the installation like the other view resolvers.
169+
throw new ContentPackException(
170+
"Invalid type for stream Stream for query filter: " + object.getClass());
164171
}
165-
return streamFilter.toBuilder().streamId(stream.getId()).build();
166172
}
167173
return filter;
168174
})

graylog2-server/src/main/java/org/graylog2/contentpacks/model/entities/SearchTypeEntity.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ public SearchType toNativeEntity(Map<String, ValueReference> parameters, Map<Ent
211211

212212
default Set<String> mappedStreams(Map<EntityDescriptor, Object> nativeEntities) {
213213
return streams().stream()
214-
.map(id -> resolveStreamReference(id, nativeEntities))
214+
.map(streamId -> resolveStreamReference(streamId, nativeEntities))
215215
.filter(Optional::isPresent)
216216
.map(Optional::get)
217217
.collect(Collectors.toSet());
@@ -224,10 +224,10 @@ default Set<String> mappedStreams(Map<EntityDescriptor, Object> nativeEntities)
224224
* skipped with a warning rather than aborting the whole content pack installation. This mirrors the export
225225
* side, which also silently drops stream references it cannot map.
226226
*/
227-
default Optional<String> resolveStreamReference(String id, Map<EntityDescriptor, Object> nativeEntities) {
228-
final Object object = resolveStreamEntityObject(id, nativeEntities);
227+
default Optional<String> resolveStreamReference(String streamId, Map<EntityDescriptor, Object> nativeEntities) {
228+
final Object object = resolveStreamEntityObject(streamId, nativeEntities);
229229
if (object == null) {
230-
LOG.warn("Skipping unresolvable stream reference <{}> for search type <{}> during content pack installation", id, id());
230+
LOG.warn("Skipping unresolvable stream reference <{}> for search type <{}> during content pack installation", streamId, id());
231231
return Optional.empty();
232232
} else if (object instanceof Stream) {
233233
return Optional.of(((Stream) object).getId());

graylog2-server/src/main/java/org/graylog2/contentpacks/model/entities/WidgetEntity.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ public WidgetDTO toNativeEntity(Map<String, ValueReference> parameters, Map<Enti
185185
.filters(filters().stream().map(filter -> filter.toNativeEntity(parameters, nativeEntities)).toList())
186186
.id(this.id())
187187
.streams(this.streams().stream()
188-
.map(id -> resolveStreamReference(id, nativeEntities))
188+
.map(streamId -> resolveStreamReference(streamId, nativeEntities))
189189
.filter(Optional::isPresent)
190190
.map(Optional::get)
191191
.collect(Collectors.toSet()))
@@ -208,10 +208,10 @@ public WidgetDTO toNativeEntity(Map<String, ValueReference> parameters, Map<Enti
208208
* side ({@link org.graylog.plugins.views.search.views.WidgetDTO#toContentPackEntity}), which also silently
209209
* drops stream references it cannot map.
210210
*/
211-
private Optional<String> resolveStreamReference(String id, Map<EntityDescriptor, Object> nativeEntities) {
212-
final Object object = resolveStreamEntityObject(id, nativeEntities);
211+
private Optional<String> resolveStreamReference(String streamId, Map<EntityDescriptor, Object> nativeEntities) {
212+
final Object object = resolveStreamEntityObject(streamId, nativeEntities);
213213
if (object == null) {
214-
LOG.warn("Skipping unresolvable stream reference <{}> for widget <{}> during content pack installation", id, id());
214+
LOG.warn("Skipping unresolvable stream reference <{}> for widget <{}> during content pack installation", streamId, id());
215215
return Optional.empty();
216216
} else if (object instanceof final Stream stream) {
217217
return Optional.of(stream.getId());

graylog2-server/src/test/java/org/graylog2/contentpacks/model/entities/QueryEntityTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,28 @@
1717
package org.graylog2.contentpacks.model.entities;
1818

1919
import com.google.common.collect.ImmutableList;
20+
import org.graylog.plugins.views.search.Filter;
2021
import org.graylog.plugins.views.search.elasticsearch.ElasticsearchQueryString;
2122
import org.graylog.plugins.views.search.filter.OrFilter;
2223
import org.graylog.plugins.views.search.filter.StreamFilter;
2324
import org.graylog.plugins.views.search.searchfilters.model.DBSearchFilter;
2425
import org.graylog.plugins.views.search.searchfilters.model.InlineQueryStringSearchFilter;
2526
import org.graylog.plugins.views.search.searchfilters.model.ReferencedQueryStringSearchFilter;
2627
import org.graylog.plugins.views.search.searchfilters.model.UsedSearchFilter;
28+
import org.graylog2.contentpacks.exceptions.ContentPackException;
2729
import org.graylog2.contentpacks.model.ModelTypes;
2830
import org.graylog2.plugin.indexer.searches.timeranges.RelativeRange;
31+
import org.graylog2.plugin.streams.Stream;
2932
import org.junit.jupiter.api.Test;
3033

3134
import java.util.Collections;
3235
import java.util.Map;
36+
import java.util.Set;
3337

3438
import static org.assertj.core.api.Assertions.assertThat;
39+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
40+
import static org.mockito.Mockito.mock;
41+
import static org.mockito.Mockito.when;
3542

3643
class QueryEntityTest {
3744

@@ -92,6 +99,47 @@ public void dropsUnresolvableStreamFilterInsteadOfFailing() {
9299
.noneMatch(f -> f instanceof StreamFilter);
93100
}
94101

102+
@Test
103+
public void keepsResolvableStreamFilterAndDropsUnresolvable() {
104+
final Stream stream = mock(Stream.class);
105+
when(stream.getId()).thenReturn("native-stream-id");
106+
final Map<EntityDescriptor, Object> nativeEntities =
107+
Map.of(EntityDescriptor.create("cp-stream-id", ModelTypes.STREAM_REF_V1), stream);
108+
109+
final QueryEntity query = QueryEntity.Builder
110+
.createWithDefaults()
111+
.id("nvmd")
112+
.timerange(RelativeRange.allTime())
113+
.query(ElasticsearchQueryString.empty())
114+
.filter(OrFilter.or(StreamFilter.ofId("cp-stream-id"), StreamFilter.ofId("missing-stream-id")))
115+
.build();
116+
117+
final Set<Filter> mappedFilters =
118+
query.toNativeEntity(Collections.emptyMap(), nativeEntities).filter().filters();
119+
120+
assertThat(mappedFilters).hasSize(1);
121+
assertThat(((StreamFilter) mappedFilters.iterator().next()).streamId()).isEqualTo("native-stream-id");
122+
}
123+
124+
@Test
125+
public void failsOnWrongTypeStreamReference() {
126+
// A non-null value that is not a Stream indicates a corrupt entity map, which must still abort the install.
127+
final Map<EntityDescriptor, Object> nativeEntities =
128+
Map.of(EntityDescriptor.create("cp-stream-id", ModelTypes.STREAM_REF_V1), "not-a-stream");
129+
130+
final QueryEntity query = QueryEntity.Builder
131+
.createWithDefaults()
132+
.id("nvmd")
133+
.timerange(RelativeRange.allTime())
134+
.query(ElasticsearchQueryString.empty())
135+
.filter(OrFilter.or(StreamFilter.ofId("cp-stream-id")))
136+
.build();
137+
138+
assertThatThrownBy(() -> query.toNativeEntity(Collections.emptyMap(), nativeEntities))
139+
.isInstanceOf(ContentPackException.class)
140+
.hasMessageContaining("Invalid type for stream");
141+
}
142+
95143
private class TestDBSearchFilter implements DBSearchFilter {
96144
String id;
97145

graylog2-server/src/test/java/org/graylog2/contentpacks/model/entities/SearchTypeEntityTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.google.common.collect.ImmutableSet;
2020
import org.graylog.plugins.views.search.SearchType;
21+
import org.graylog2.contentpacks.exceptions.ContentPackException;
2122
import org.graylog2.contentpacks.model.ModelTypes;
2223
import org.graylog2.plugin.streams.Stream;
2324
import org.junit.jupiter.api.Test;
@@ -26,6 +27,7 @@
2627
import java.util.Map;
2728

2829
import static org.assertj.core.api.Assertions.assertThat;
30+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
2931
import static org.mockito.Mockito.mock;
3032
import static org.mockito.Mockito.when;
3133

@@ -59,4 +61,37 @@ public void keepsResolvableStreamReference() {
5961

6062
assertThat(nativeEntity.streams()).containsExactly("native-stream-id");
6163
}
64+
65+
@Test
66+
public void dropsOnlyUnresolvableStreamReferences() {
67+
final Stream stream = mock(Stream.class);
68+
when(stream.getId()).thenReturn("native-stream-id");
69+
final Map<EntityDescriptor, Object> nativeEntities =
70+
Map.of(EntityDescriptor.create("cp-stream-id", ModelTypes.STREAM_REF_V1), stream);
71+
72+
final MessageListEntity searchType = MessageListEntity.builder()
73+
.id("search-type-id")
74+
.streams(ImmutableSet.of("cp-stream-id", "missing-stream-id"))
75+
.build();
76+
77+
final SearchType nativeEntity = searchType.toNativeEntity(Collections.emptyMap(), nativeEntities);
78+
79+
assertThat(nativeEntity.streams()).containsExactly("native-stream-id");
80+
}
81+
82+
@Test
83+
public void failsOnWrongTypeStreamReference() {
84+
// A non-null value that is not a Stream indicates a corrupt entity map, which must still abort the install.
85+
final Map<EntityDescriptor, Object> nativeEntities =
86+
Map.of(EntityDescriptor.create("cp-stream-id", ModelTypes.STREAM_REF_V1), "not-a-stream");
87+
88+
final MessageListEntity searchType = MessageListEntity.builder()
89+
.id("search-type-id")
90+
.streams(ImmutableSet.of("cp-stream-id"))
91+
.build();
92+
93+
assertThatThrownBy(() -> searchType.toNativeEntity(Collections.emptyMap(), nativeEntities))
94+
.isInstanceOf(ContentPackException.class)
95+
.hasMessageContaining("Invalid type for stream");
96+
}
6297
}

graylog2-server/src/test/java/org/graylog2/contentpacks/model/entities/WidgetEntityTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.graylog.plugins.views.search.elasticsearch.ElasticsearchQueryString;
2121
import org.graylog.plugins.views.search.views.WidgetDTO;
2222
import org.graylog.plugins.views.search.views.widgets.messagelist.MessageListConfigDTO;
23+
import org.graylog2.contentpacks.exceptions.ContentPackException;
2324
import org.graylog2.contentpacks.model.ModelTypes;
2425
import org.graylog2.plugin.indexer.searches.timeranges.KeywordRange;
2526
import org.graylog2.plugin.streams.Stream;
@@ -30,6 +31,7 @@
3031
import java.util.Set;
3132

3233
import static org.assertj.core.api.Assertions.assertThat;
34+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
3335
import static org.mockito.Mockito.mock;
3436
import static org.mockito.Mockito.when;
3537

@@ -71,4 +73,31 @@ public void keepsResolvableStreamReference() {
7173

7274
assertThat(nativeEntity.streams()).containsExactly("native-stream-id");
7375
}
76+
77+
@Test
78+
public void dropsOnlyUnresolvableStreamReferences() {
79+
final Stream stream = mock(Stream.class);
80+
when(stream.getId()).thenReturn("native-stream-id");
81+
final Map<EntityDescriptor, Object> nativeEntities =
82+
Map.of(EntityDescriptor.create("cp-stream-id", ModelTypes.STREAM_REF_V1), stream);
83+
84+
final WidgetEntity widget = widgetBuilder(ImmutableSet.of("cp-stream-id", "missing-stream-id")).build();
85+
86+
final WidgetDTO nativeEntity = widget.toNativeEntity(Collections.emptyMap(), nativeEntities);
87+
88+
assertThat(nativeEntity.streams()).containsExactly("native-stream-id");
89+
}
90+
91+
@Test
92+
public void failsOnWrongTypeStreamReference() {
93+
// A non-null value that is not a Stream indicates a corrupt entity map, which must still abort the install.
94+
final Map<EntityDescriptor, Object> nativeEntities =
95+
Map.of(EntityDescriptor.create("cp-stream-id", ModelTypes.STREAM_REF_V1), "not-a-stream");
96+
97+
final WidgetEntity widget = widgetBuilder(ImmutableSet.of("cp-stream-id")).build();
98+
99+
assertThatThrownBy(() -> widget.toNativeEntity(Collections.emptyMap(), nativeEntities))
100+
.isInstanceOf(ContentPackException.class)
101+
.hasMessageContaining("Invalid type for stream");
102+
}
74103
}

0 commit comments

Comments
 (0)