diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2021-09-07 18:04:14 +0200 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2021-09-07 18:04:14 +0200 |
commit | af21aef7bcd924ced077686720a32dba1337a474 (patch) | |
tree | 2e21928efa80244b3d70733cb7445eae16285aad /config-model | |
parent | 24504d25acafe592c1109eb1fb89d5250928aa5c (diff) |
Detect cyclic inheritance.
This can not be hidden, as it will cause StackOverflowException.
Diffstat (limited to 'config-model')
-rw-r--r-- | config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java | 23 | ||||
-rw-r--r-- | config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java | 19 |
2 files changed, 38 insertions, 4 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java b/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java index 96dab55b16f..19933222587 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java @@ -211,7 +211,7 @@ public class RankProfile implements Cloneable { public String getInheritedName() { return inheritedName; } /** Returns the inherited rank profile, or null if there is none */ - public RankProfile getInherited() { + private RankProfile getInherited() { if (inheritedName == null) return null; if (inherited == null) { inherited = resolveInherited(); @@ -224,17 +224,32 @@ public class RankProfile implements Cloneable { } else { log.warning(msg); } + } else { + List<String> children = new ArrayList<>(); + children.add(getName()); + verifyNoInheritanceCycle(children, inherited); } } return inherited; } + private void verifyNoInheritanceCycle(List<String> children, RankProfile parent) { + children.add(parent.getName()); + String root = children.get(0); + if (root.equals(parent.getName())) { + throw new IllegalArgumentException("There is a cycle in the inheritance for rank-profile '" + root + "' = " + children); + } + if (parent.getInherited() != null) { + verifyNoInheritanceCycle(children, parent.getInherited()); + } + } + private RankProfile resolveInherited() { if (inheritedName == null) return null; return (getSearch() != null) - ? (search.getDocument() != null) - ? rankProfileRegistry.resolve(search.getDocument(), inheritedName) - : rankProfileRegistry.get(search.getName(), inheritedName) + ? ((search.getDocument() != null) + ? rankProfileRegistry.resolve(search.getDocument(), inheritedName) + : rankProfileRegistry.get(search.getName(), inheritedName)) : rankProfileRegistry.getGlobal(inheritedName); } diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java index fe094e6e980..a728acf29e7 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java @@ -97,6 +97,25 @@ public class RankProfileTestCase extends SchemaTestCase { } @Test + public void requireThatCyclicInheritanceIsIllegal() throws ParseException { + try { + RankProfileRegistry registry = new RankProfileRegistry(); + SearchBuilder builder = new SearchBuilder(registry, setupQueryProfileTypes()); + builder.importString( + "search test {\n" + + " document test { } \n" + + " rank-profile a inherits b {}\n" + + " rank-profile b inherits c {}\n" + + " rank-profile c inherits a {}\n" + + "}"); + builder.build(true); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("There is a cycle in the inheritance for rank-profile 'c' = [c, a, b, c]", e.getMessage()); + } + } + + @Test public void requireThatRankProfilesCanInheritNotYetSeenProfiles() throws ParseException { RankProfileRegistry registry = new RankProfileRegistry(); |