|  | 
|  | 1 | +/* | 
|  | 2 | + * Copyright OpenSearch Contributors | 
|  | 3 | + * SPDX-License-Identifier: Apache-2.0 | 
|  | 4 | + */ | 
|  | 5 | + | 
|  | 6 | +package org.opensearch.agent.tools; | 
|  | 7 | + | 
|  | 8 | +import static org.junit.Assert.assertEquals; | 
|  | 9 | +import static org.mockito.ArgumentMatchers.any; | 
|  | 10 | +import static org.mockito.Mockito.times; | 
|  | 11 | +import static org.mockito.Mockito.verify; | 
|  | 12 | +import static org.mockito.Mockito.when; | 
|  | 13 | + | 
|  | 14 | +import java.util.HashMap; | 
|  | 15 | +import java.util.Map; | 
|  | 16 | + | 
|  | 17 | +import org.apache.commons.text.StringEscapeUtils; | 
|  | 18 | +import org.junit.Before; | 
|  | 19 | +import org.junit.Test; | 
|  | 20 | +import org.mockito.ArgumentCaptor; | 
|  | 21 | +import org.mockito.Mock; | 
|  | 22 | +import org.mockito.MockitoAnnotations; | 
|  | 23 | +import org.opensearch.core.action.ActionListener; | 
|  | 24 | +import org.opensearch.script.ScriptService; | 
|  | 25 | +import org.opensearch.script.TemplateScript; | 
|  | 26 | + | 
|  | 27 | +import com.google.gson.Gson; | 
|  | 28 | + | 
|  | 29 | +/** | 
|  | 30 | + * this is a test file to test PainlessTool with junit | 
|  | 31 | + */ | 
|  | 32 | +public class PainlessToolTests { | 
|  | 33 | +    @Mock | 
|  | 34 | +    private ScriptService scriptService; | 
|  | 35 | +    @Mock | 
|  | 36 | +    private TemplateScript templateScript; | 
|  | 37 | +    @Mock | 
|  | 38 | +    private ActionListener<String> actionListener; | 
|  | 39 | + | 
|  | 40 | +    @Before | 
|  | 41 | +    public void setup() { | 
|  | 42 | +        MockitoAnnotations.openMocks(this); | 
|  | 43 | +        TemplateScript.Factory factory = new TemplateScript.Factory() { | 
|  | 44 | +            @Override | 
|  | 45 | +            public TemplateScript newInstance(Map<String, Object> params) { | 
|  | 46 | +                return templateScript; | 
|  | 47 | +            } | 
|  | 48 | +        }; | 
|  | 49 | + | 
|  | 50 | +        when(scriptService.compile(any(), any())).thenReturn(factory); | 
|  | 51 | + | 
|  | 52 | +        PainlessTool.Factory.getInstance().init(scriptService); | 
|  | 53 | +    } | 
|  | 54 | + | 
|  | 55 | +    @Test | 
|  | 56 | +    public void testRun() { | 
|  | 57 | +        String script = "return 'Hello World';"; | 
|  | 58 | +        PainlessTool tool = PainlessTool.Factory.getInstance().create(Map.of("script", script)); | 
|  | 59 | +        when(templateScript.execute()).thenReturn("hello"); | 
|  | 60 | +        tool.run(Map.of(), actionListener); | 
|  | 61 | + | 
|  | 62 | +        verify(templateScript).execute(); | 
|  | 63 | +        verify(scriptService).compile(any(), any()); | 
|  | 64 | +        ArgumentCaptor<String> responseCaptor = ArgumentCaptor.forClass(String.class); | 
|  | 65 | +        verify(actionListener, times(1)).onResponse(responseCaptor.capture()); | 
|  | 66 | +        assertEquals("hello", responseCaptor.getValue()); | 
|  | 67 | +    } | 
|  | 68 | + | 
|  | 69 | +    // test run wit exception | 
|  | 70 | +    @Test | 
|  | 71 | +    public void testRun_with_exception() { | 
|  | 72 | +        String script = "return 'Hello World';"; | 
|  | 73 | +        PainlessTool tool = PainlessTool.Factory.getInstance().create(Map.of("script", script)); | 
|  | 74 | +        when(templateScript.execute()).thenThrow(new RuntimeException("error")); | 
|  | 75 | +        tool.run(Map.of(), actionListener); | 
|  | 76 | + | 
|  | 77 | +        verify(templateScript).execute(); | 
|  | 78 | +        verify(scriptService).compile(any(), any()); | 
|  | 79 | +        ArgumentCaptor<Exception> exceptionCaptor = ArgumentCaptor.forClass(Exception.class); | 
|  | 80 | +        verify(actionListener, times(1)).onFailure(exceptionCaptor.capture()); | 
|  | 81 | +        assertEquals("error", exceptionCaptor.getValue().getMessage()); | 
|  | 82 | +    } | 
|  | 83 | + | 
|  | 84 | +    // test factory create | 
|  | 85 | +    @Test | 
|  | 86 | +    public void testFactory_create() { | 
|  | 87 | +        String script = "return 'Hello World';"; | 
|  | 88 | +        PainlessTool tool = PainlessTool.Factory.getInstance().create(Map.of("script", script)); | 
|  | 89 | +        assertEquals(PainlessTool.TYPE, tool.getType()); | 
|  | 90 | +        assertEquals("PainlessTool", tool.getName()); | 
|  | 91 | +        assertEquals("Use this tool to execute painless script", tool.getDescription()); | 
|  | 92 | +    } | 
|  | 93 | + | 
|  | 94 | +    // test factory create with exception | 
|  | 95 | +    @Test(expected = IllegalArgumentException.class) | 
|  | 96 | +    public void testFactory_create_with_exception() { | 
|  | 97 | +        PainlessTool.Factory.getInstance().create(Map.of()); | 
|  | 98 | +    } | 
|  | 99 | + | 
|  | 100 | +    // test flattenMap | 
|  | 101 | +    @Test | 
|  | 102 | +    public void testFlattenMap_without_prefix() { | 
|  | 103 | +        String script = "return 'Hello World';"; | 
|  | 104 | +        PainlessTool tool = PainlessTool.Factory.getInstance().create(Map.of("script", script)); | 
|  | 105 | +        Map<String, Object> map = Map.of("a", Map.of("b", "c"), "k", "v"); | 
|  | 106 | +        Map<String, Object> resultMap = new HashMap<>(); | 
|  | 107 | +        tool.flattenMap(map, resultMap, ""); | 
|  | 108 | +        assertEquals(Map.of("a.b", "c", "k", "v"), resultMap); | 
|  | 109 | +    } | 
|  | 110 | + | 
|  | 111 | +    // with prefix | 
|  | 112 | +    @Test | 
|  | 113 | +    public void testFlattenMap_with_prefix() { | 
|  | 114 | +        String script = "return 'Hello World';"; | 
|  | 115 | +        PainlessTool tool = PainlessTool.Factory.getInstance().create(Map.of("script", script)); | 
|  | 116 | +        Map<String, Object> map = Map.of("a", Map.of("b", "c"), "k", "v"); | 
|  | 117 | +        Map<String, Object> resultMap = new HashMap<>(); | 
|  | 118 | +        tool.flattenMap(map, resultMap, "prefix"); | 
|  | 119 | +        assertEquals(Map.of("prefix.a.b", "c", "prefix.k", "v"), resultMap); | 
|  | 120 | +    } | 
|  | 121 | + | 
|  | 122 | +    // nest map with depth 3 | 
|  | 123 | +    @Test | 
|  | 124 | +    public void testFlattenMap_with_depth_3() { | 
|  | 125 | +        String script = "return 'Hello World';"; | 
|  | 126 | +        PainlessTool tool = PainlessTool.Factory.getInstance().create(Map.of("script", script)); | 
|  | 127 | +        Map<String, Object> map = Map.of("a", Map.of("b", Map.of("c", "d"), "k", "v")); | 
|  | 128 | +        Gson gson = new Gson(); | 
|  | 129 | +        System.out.println(StringEscapeUtils.escapeJson(gson.toJson(map))); | 
|  | 130 | +        Map<String, Object> resultMap = new HashMap<>(); | 
|  | 131 | +        tool.flattenMap(map, resultMap, ""); | 
|  | 132 | +        assertEquals(Map.of("a.b.c", "d", "a.k", "v"), resultMap); | 
|  | 133 | +    } | 
|  | 134 | + | 
|  | 135 | +    // test getFlattenedParameters | 
|  | 136 | +    @Test | 
|  | 137 | +    public void testGetFlattenedParameters() { | 
|  | 138 | +        String script = "return 'Hello World';"; | 
|  | 139 | +        PainlessTool tool = PainlessTool.Factory.getInstance().create(Map.of("script", script)); | 
|  | 140 | +        Map<String, String> map = Map.of("k", "{\\\"a\\\":{\\\"k\\\":\\\"v\\\",\\\"b\\\":{\\\"c\\\":\\\"d\\\"}}}"); | 
|  | 141 | +        Map<String, Object> resultMap = tool.getFlattenedParameters(map); | 
|  | 142 | +        assertEquals( | 
|  | 143 | +            Map.of("k.a.b.c", "d", "k.a.k", "v", "k", "{\\\"a\\\":{\\\"k\\\":\\\"v\\\",\\\"b\\\":{\\\"c\\\":\\\"d\\\"}}}"), | 
|  | 144 | +            resultMap | 
|  | 145 | +        ); | 
|  | 146 | +    } | 
|  | 147 | +} | 
0 commit comments