From ad6ea1158d44562ba915b6f42ee0388ef1c6693e Mon Sep 17 00:00:00 2001 From: Daniel Widdis Date: Fri, 22 Sep 2023 17:10:11 -0700 Subject: [PATCH] Test exceptional cases Signed-off-by: Daniel Widdis --- .../flowframework/template/WorkflowNode.java | 4 ++ .../template/WorkflowEdgeTests.java | 15 +++++-- .../template/WorkflowNodeTests.java | 40 +++++++++++++++---- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/opensearch/flowframework/template/WorkflowNode.java b/src/main/java/org/opensearch/flowframework/template/WorkflowNode.java index 00c09b263..d1f493ca9 100644 --- a/src/main/java/org/opensearch/flowframework/template/WorkflowNode.java +++ b/src/main/java/org/opensearch/flowframework/template/WorkflowNode.java @@ -70,6 +70,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws } else if (e.getValue() instanceof Map) { Template.buildStringToStringMap(xContentBuilder, (Map) e.getValue()); } else if (e.getValue() instanceof Object[]) { + // This assumes an array of maps for "processor" key xContentBuilder.startArray(); for (Map map : (Map[]) e.getValue()) { Template.buildStringToStringMap(xContentBuilder, map); @@ -113,6 +114,9 @@ public static WorkflowNode parse(XContentParser parser) throws IOException { case VALUE_STRING: inputs.put(inputFieldName, parser.text()); break; + case START_OBJECT: + inputs.put(inputFieldName, Template.parseStringToStringMap(parser)); + break; case START_ARRAY: List> mapList = new ArrayList<>(); while (parser.nextToken() != XContentParser.Token.END_ARRAY) { diff --git a/src/test/java/org/opensearch/flowframework/template/WorkflowEdgeTests.java b/src/test/java/org/opensearch/flowframework/template/WorkflowEdgeTests.java index 358081ef8..f6b61fb52 100644 --- a/src/test/java/org/opensearch/flowframework/template/WorkflowEdgeTests.java +++ b/src/test/java/org/opensearch/flowframework/template/WorkflowEdgeTests.java @@ -8,7 +8,6 @@ */ package org.opensearch.flowframework.template; -import org.opensearch.core.xcontent.XContentParser; import org.opensearch.test.OpenSearchTestCase; import java.io.IOException; @@ -36,10 +35,20 @@ public void testEdge() throws IOException { String json = TemplateTestJsonUtil.parseToJson(edgeAB); assertEquals(expectedJson, json); - XContentParser parser = TemplateTestJsonUtil.jsonToParser(json); - WorkflowEdge edgeX = WorkflowEdge.parse(parser); + WorkflowEdge edgeX = WorkflowEdge.parse(TemplateTestJsonUtil.jsonToParser(json)); assertEquals("A", edgeX.source()); assertEquals("B", edgeX.destination()); assertEquals("A->B", edgeX.toString()); } + + public void testExceptions() throws IOException { + String badJson = "{\"badField\":\"A\",\"dest\":\"B\"}"; + IOException e = assertThrows(IOException.class, () -> WorkflowEdge.parse(TemplateTestJsonUtil.jsonToParser(badJson))); + assertEquals("Unable to parse field [badField] in an edge object.", e.getMessage()); + + String missingJson = "{\"dest\":\"B\"}"; + e = assertThrows(IOException.class, () -> WorkflowEdge.parse(TemplateTestJsonUtil.jsonToParser(missingJson))); + assertEquals("An edge object requires both a source and dest field.", e.getMessage()); + } + } diff --git a/src/test/java/org/opensearch/flowframework/template/WorkflowNodeTests.java b/src/test/java/org/opensearch/flowframework/template/WorkflowNodeTests.java index 83d0dcd5a..157edfc01 100644 --- a/src/test/java/org/opensearch/flowframework/template/WorkflowNodeTests.java +++ b/src/test/java/org/opensearch/flowframework/template/WorkflowNodeTests.java @@ -8,7 +8,6 @@ */ package org.opensearch.flowframework.template; -import org.opensearch.core.xcontent.XContentParser; import org.opensearch.test.OpenSearchTestCase; import java.io.IOException; @@ -22,10 +21,21 @@ public void setUp() throws Exception { } public void testNode() throws IOException { - WorkflowNode nodeA = new WorkflowNode("A", "a-type", Map.of("foo", "bar")); + WorkflowNode nodeA = new WorkflowNode( + "A", + "a-type", + Map.ofEntries( + Map.entry("foo", "a string"), + Map.entry("bar", Map.of("key", "value")), + Map.entry("baz", new Map[] { Map.of("A", "a"), Map.of("B", "b") }) + ) + ); assertEquals("A", nodeA.id()); assertEquals("a-type", nodeA.type()); - assertEquals(Map.of("foo", "bar"), nodeA.inputs()); + Map map = nodeA.inputs(); + assertEquals("a string", (String) map.get("foo")); + assertEquals(Map.of("key", "value"), (Map) map.get("bar")); + assertArrayEquals(new Map[] { Map.of("A", "a"), Map.of("B", "b") }, (Map[]) map.get("baz")); // node equality is based only on ID WorkflowNode nodeA2 = new WorkflowNode("A", "a2-type", Map.of("bar", "baz")); @@ -34,14 +44,28 @@ public void testNode() throws IOException { WorkflowNode nodeB = new WorkflowNode("B", "b-type", Map.of("baz", "qux")); assertNotEquals(nodeA, nodeB); - String expectedJson = "{\"id\":\"A\",\"type\":\"a-type\",\"inputs\":{\"foo\":\"bar\"}}"; String json = TemplateTestJsonUtil.parseToJson(nodeA); - assertEquals(expectedJson, json); + assertTrue(json.startsWith("{\"id\":\"A\",\"type\":\"a-type\",\"inputs\":")); + assertTrue(json.contains("\"foo\":\"a string\"")); + assertTrue(json.contains("\"baz\":[{\"A\":\"a\"},{\"B\":\"b\"}]")); + assertTrue(json.contains("\"bar\":{\"key\":\"value\"}")); - XContentParser parser = TemplateTestJsonUtil.jsonToParser(json); - WorkflowNode nodeX = WorkflowNode.parse(parser); + WorkflowNode nodeX = WorkflowNode.parse(TemplateTestJsonUtil.jsonToParser(json)); assertEquals("A", nodeX.id()); assertEquals("a-type", nodeX.type()); - assertEquals(Map.of("foo", "bar"), nodeX.inputs()); + Map mapX = nodeX.inputs(); + assertEquals("a string", mapX.get("foo")); + assertEquals(Map.of("key", "value"), mapX.get("bar")); + assertArrayEquals(new Map[] { Map.of("A", "a"), Map.of("B", "b") }, (Map[]) map.get("baz")); + } + + public void testExceptions() throws IOException { + String badJson = "{\"badField\":\"A\",\"type\":\"a-type\",\"inputs\":{\"foo\":\"bar\"}}"; + IOException e = assertThrows(IOException.class, () -> WorkflowNode.parse(TemplateTestJsonUtil.jsonToParser(badJson))); + assertEquals("Unable to parse field [badField] in a node object.", e.getMessage()); + + String missingJson = "{\"id\":\"A\",\"inputs\":{\"foo\":\"bar\"}}"; + e = assertThrows(IOException.class, () -> WorkflowNode.parse(TemplateTestJsonUtil.jsonToParser(missingJson))); + assertEquals("An node object requires both an id and type field.", e.getMessage()); } }