/* * JBoss, Home of Professional Open Source * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors * as indicated by the @authors tag. All rights reserved. */ package org.jboss.elasticsearch.tools.content; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.junit.Assert; import org.junit.Test; /** * Unit test for {@link StructureUtils}. * * @author Vlastimil Elias (velias at redhat dot com) * @author Ryszard Kozmik (rkozmik at redhat dot com) */ public class StructureUtilsTest { private static final String TEST_KEY = "tkey"; @Test public void getIntegerValue() { Assert.assertNull(StructureUtils.getIntegerValue(null, "aa")); Map<String, Object> values = new HashMap<String, Object>(); try { Assert.assertNull(StructureUtils.getIntegerValue(values, null)); Assert.fail(); } catch (IllegalArgumentException e) { // ok } try { Assert.assertNull(StructureUtils.getIntegerValue(values, " ")); Assert.fail(); } catch (IllegalArgumentException e) { // ok } Assert.assertNull(StructureUtils.getIntegerValue(values, TEST_KEY)); values.put(TEST_KEY, new Integer(10)); Assert.assertEquals(new Integer(10), StructureUtils.getIntegerValue(values, TEST_KEY)); values.put(TEST_KEY, new Short("1")); Assert.assertEquals(new Integer(1), StructureUtils.getIntegerValue(values, TEST_KEY)); values.put(TEST_KEY, new Long("1000")); Assert.assertEquals(new Integer(1000), StructureUtils.getIntegerValue(values, TEST_KEY)); values.put(TEST_KEY, "100"); Assert.assertEquals(new Integer(100), StructureUtils.getIntegerValue(values, TEST_KEY)); try { values.put(TEST_KEY, "ahoj"); Assert.assertEquals(new Integer(10), StructureUtils.getIntegerValue(values, TEST_KEY)); Assert.fail("No NumberFormatException thrown."); } catch (NumberFormatException e) { // OK } } @Test public void getStringValue() { Assert.assertNull(StructureUtils.getStringValue(null, "aa")); Map<String, Object> values = new HashMap<String, Object>(); try { Assert.assertNull(StructureUtils.getStringValue(values, null)); Assert.fail(); } catch (IllegalArgumentException e) { // ok } try { Assert.assertNull(StructureUtils.getStringValue(values, " ")); Assert.fail(); } catch (IllegalArgumentException e) { // ok } Assert.assertNull(StructureUtils.getStringValue(values, TEST_KEY)); values.put(TEST_KEY, new Integer(10)); Assert.assertEquals("10", StructureUtils.getStringValue(values, TEST_KEY)); values.put(TEST_KEY, new Short("1")); Assert.assertEquals("1", StructureUtils.getStringValue(values, TEST_KEY)); values.put(TEST_KEY, new Long("1000")); Assert.assertEquals("1000", StructureUtils.getStringValue(values, TEST_KEY)); values.put(TEST_KEY, "100"); Assert.assertEquals("100", StructureUtils.getStringValue(values, TEST_KEY)); } @Test public void getListOfStringValues() { // case - null result from null data Assert.assertNull(StructureUtils.getListOfStringValues(null, "aa")); // case - key param validation Map<String, Object> values = new HashMap<String, Object>(); try { Assert.assertNull(StructureUtils.getListOfStringValues(values, null)); Assert.fail(); } catch (IllegalArgumentException e) { // ok } try { Assert.assertNull(StructureUtils.getListOfStringValues(values, " ")); Assert.fail(); } catch (IllegalArgumentException e) { // ok } // case - null result for nonexisting case Assert.assertNull(StructureUtils.getListOfStringValues(values, TEST_KEY)); // case - simple String values handling values.put(TEST_KEY, "teststring"); Assert.assertEquals(1, StructureUtils.getListOfStringValues(values, TEST_KEY).size()); Assert.assertEquals("teststring", StructureUtils.getListOfStringValues(values, TEST_KEY).get(0)); values.put(TEST_KEY, ""); Assert.assertNull(StructureUtils.getListOfStringValues(values, TEST_KEY)); values.put(TEST_KEY, " "); Assert.assertNull(StructureUtils.getListOfStringValues(values, TEST_KEY)); // case - simple other values handling values.put(TEST_KEY, new Integer(10)); Assert.assertEquals(1, StructureUtils.getListOfStringValues(values, TEST_KEY).size()); Assert.assertEquals("10", StructureUtils.getListOfStringValues(values, TEST_KEY).get(0)); // case - Map value handling - results in null Map<String, Object> tm = new HashMap<String, Object>(); tm.put("a", "b"); values.put(TEST_KEY, tm); Assert.assertNull(StructureUtils.getListOfStringValues(values, TEST_KEY)); // case - List of values handling List<Object> l = new ArrayList<Object>(); values.put(TEST_KEY, l); Assert.assertNull(StructureUtils.getListOfStringValues(values, TEST_KEY)); l.add("aa"); Assert.assertEquals(1, StructureUtils.getListOfStringValues(values, TEST_KEY).size()); Assert.assertEquals("aa", StructureUtils.getListOfStringValues(values, TEST_KEY).get(0)); l.add(new Integer(10)); Assert.assertEquals(2, StructureUtils.getListOfStringValues(values, TEST_KEY).size()); Assert.assertEquals("aa", StructureUtils.getListOfStringValues(values, TEST_KEY).get(0)); Assert.assertEquals("10", StructureUtils.getListOfStringValues(values, TEST_KEY).get(1)); } @Test public void filterDataInMap() { // case - no exceptions on distinct null and empty inputs StructureUtils.filterDataInMap(null, null); Set<String> keysToLeave = new HashSet<String>(); StructureUtils.filterDataInMap(null, keysToLeave); Map<String, Object> map = new HashMap<String, Object>(); StructureUtils.filterDataInMap(map, null); StructureUtils.filterDataInMap(map, keysToLeave); keysToLeave.add("key1"); StructureUtils.filterDataInMap(null, keysToLeave); StructureUtils.filterDataInMap(map, keysToLeave); // case - no filtering on null or empty keysToLeave keysToLeave.clear(); map.clear(); map.put("key1", "val1"); map.put("key2", "val2"); StructureUtils.filterDataInMap(map, null); Assert.assertEquals(2, map.size()); StructureUtils.filterDataInMap(map, keysToLeave); Assert.assertEquals(2, map.size()); // case - filtering works map.clear(); keysToLeave.clear(); map.put("key2", "val2"); keysToLeave.add("key2"); StructureUtils.filterDataInMap(map, keysToLeave); Assert.assertEquals(1, map.size()); Assert.assertTrue(map.containsKey("key2")); map.clear(); keysToLeave.clear(); map.put("key1", "val1"); map.put("key2", "val2"); map.put("key3", "val3"); map.put("key4", "val4"); keysToLeave.add("key2"); keysToLeave.add("key3"); StructureUtils.filterDataInMap(map, keysToLeave); Assert.assertEquals(2, map.size()); Assert.assertTrue(map.containsKey("key2")); Assert.assertTrue(map.containsKey("key3")); } @Test public void remapDataInMap() { // case - no exceptions on distinct null and empty inputs StructureUtils.remapDataInMap(null, null); Map<String, String> remapInstructions = new LinkedHashMap<String, String>(); StructureUtils.remapDataInMap(null, remapInstructions); Map<String, Object> map = new LinkedHashMap<String, Object>(); StructureUtils.remapDataInMap(map, null); StructureUtils.remapDataInMap(map, remapInstructions); remapInstructions.put("key1", "key1new"); StructureUtils.remapDataInMap(null, remapInstructions); StructureUtils.remapDataInMap(map, remapInstructions); // case - no change in map if remap instruction is null or empty remapInstructions.clear(); map.put("key1", "value1"); map.put("key2", "value2"); StructureUtils.remapDataInMap(map, null); Assert.assertEquals(2, map.size()); Assert.assertEquals("value1", map.get("key1")); Assert.assertEquals("value2", map.get("key2")); StructureUtils.remapDataInMap(map, remapInstructions); Assert.assertEquals(2, map.size()); Assert.assertEquals("value1", map.get("key1")); Assert.assertEquals("value2", map.get("key2")); // case remap some values and filter out some other and leave some untouched map.clear(); remapInstructions.clear(); map.put("key1", "value1"); map.put("key2", "value2"); map.put("key3", "value3"); map.put("key4", "value4"); map.put("key5", "value5"); map.put("key6", "value6"); map.put("key7", "value7"); map.put("key8", "value8"); map.put("key9", "value9"); map.put("key10", "value10"); remapInstructions.put("key1", "key1new"); remapInstructions.put("key3", "key3"); remapInstructions.put("key4", "key5"); remapInstructions.put("key6", "key4"); remapInstructions.put("key7", "key8"); remapInstructions.put("key8", "key7"); remapInstructions.put("key10", "key10new"); StructureUtils.remapDataInMap(map, remapInstructions); Assert.assertEquals(7, map.size()); Assert.assertEquals("value1", map.get("key1new")); Assert.assertFalse(map.containsKey("key2")); Assert.assertEquals("value3", map.get("key3")); Assert.assertEquals("value4", map.get("key5")); Assert.assertEquals("value6", map.get("key4")); Assert.assertEquals("value7", map.get("key8")); Assert.assertEquals("value8", map.get("key7")); Assert.assertFalse(map.containsKey("key9")); Assert.assertEquals("value10", map.get("key10new")); } @Test public void putValueIntoMapOfMaps() { // case - not NPE on empty data map StructureUtils.putValueIntoMapOfMaps(null, "field", null); Map<String, Object> map = new HashMap<String, Object>(); // case - exception on invalid field definition try { StructureUtils.putValueIntoMapOfMaps(map, null, null); Assert.fail("IllegalArgumentException must be thrown"); } catch (IllegalArgumentException e) { // OK } try { StructureUtils.putValueIntoMapOfMaps(map, " ", null); Assert.fail("IllegalArgumentException must be thrown"); } catch (IllegalArgumentException e) { // OK } // case - simplefield - insert null can produce null even if it was set previously StructureUtils.putValueIntoMapOfMaps(map, "field", null); Assert.assertNull(map.get("field")); map.put("field", "value"); StructureUtils.putValueIntoMapOfMaps(map, "field", null); Assert.assertNull(map.get("field")); // case - simplefield - insert and replace value map.clear(); StructureUtils.putValueIntoMapOfMaps(map, "field", "value"); Assert.assertEquals("value", map.get("field")); StructureUtils.putValueIntoMapOfMaps(map, "field", "value2"); Assert.assertEquals("value2", map.get("field")); // case- dot notation map.clear(); StructureUtils.putValueIntoMapOfMaps(map, "field.level1.level11", "value"); Assert.assertEquals("value", XContentMapValues.extractValue("field.level1.level11", map)); StructureUtils.putValueIntoMapOfMaps(map, "field.level1.level12", "value2"); Assert.assertEquals("value2", XContentMapValues.extractValue("field.level1.level12", map)); // case - dot notation structure error leads to exception try { map.clear(); map.put("field", "dsd"); StructureUtils.putValueIntoMapOfMaps(map, "field.level1.level11", "value"); Assert.fail("IllegalArgumentException must be thrown"); } catch (IllegalArgumentException e) { // OK } try { map.clear(); map.put("field", new ArrayList<Object>()); StructureUtils.putValueIntoMapOfMaps(map, "field.level1.level11", "value"); Assert.fail("IllegalArgumentException must be thrown"); } catch (IllegalArgumentException e) { // OK } } @Test public void removeValueFromMapOfMaps() { // case - not NPE on empty data map Assert.assertNull(StructureUtils.removeValueFromMapOfMaps(null, "field")); Map<String, Object> map = new HashMap<String, Object>(); // case - exception on invalid field definition try { StructureUtils.removeValueFromMapOfMaps(map, null); Assert.fail("IllegalArgumentException must be thrown"); } catch (IllegalArgumentException e) { // OK } try { StructureUtils.removeValueFromMapOfMaps(map, " "); Assert.fail("IllegalArgumentException must be thrown"); } catch (IllegalArgumentException e) { // OK } // case - simplefield - not present in map map.clear(); Assert.assertNull(StructureUtils.removeValueFromMapOfMaps(map, "field")); // case - simplefield - removed simple value map.clear(); map.put("field", "aaa"); Map<String, Object> m1 = new HashMap<String, Object>(); map.put("field2", m1); Assert.assertEquals("aaa", StructureUtils.removeValueFromMapOfMaps(map, "field")); Assert.assertEquals(m1, StructureUtils.removeValueFromMapOfMaps(map, "field2")); // case - dot notation - remove simple value StructureUtils.putValueIntoMapOfMaps(map, "field.level1.level11", "value"); Assert.assertEquals("value", StructureUtils.removeValueFromMapOfMaps(map, "field.level1.level11")); Assert.assertNull(XContentMapValues.extractValue("field.level1.level11", map)); // case - dot notation - remove submap StructureUtils.putValueIntoMapOfMaps(map, "field.level1.level11", "value"); Assert.assertTrue(StructureUtils.removeValueFromMapOfMaps(map, "field.level1") instanceof Map); Assert.assertNull(XContentMapValues.extractValue("field.level1", map)); // case - dot notation - remove List StructureUtils.putValueIntoMapOfMaps(map, "field.level1.level11", new ArrayList<Object>()); Assert.assertTrue(StructureUtils.removeValueFromMapOfMaps(map, "field.level1.level11") instanceof List); Assert.assertNull(XContentMapValues.extractValue("field.level1.level11", map)); // case - dot notation - remove from nonexisting submap is OK Assert.assertNull(StructureUtils.removeValueFromMapOfMaps(map, "field.level1.level11")); // case - dot notation structure error leads to exception try { map.clear(); map.put("field", "dsd"); StructureUtils.removeValueFromMapOfMaps(map, "field.field1"); Assert.fail("IllegalArgumentException must be thrown"); } catch (IllegalArgumentException e) { // OK } try { map.clear(); map.put("field", new ArrayList<Object>()); StructureUtils.removeValueFromMapOfMaps(map, "field.field1"); Assert.fail("IllegalArgumentException must be thrown"); } catch (IllegalArgumentException e) { // OK } } @SuppressWarnings("unchecked") @Test public void getADeepStructureCopy() { // case - not NPE on empty data map Assert.assertNull(StructureUtils.getADeepStructureCopy(null)); // case - if we give a value that is not a Map or a List, just an immutable value // it should return the same object. String exampleValue = "example"; Assert.assertSame(exampleValue, StructureUtils.getADeepStructureCopy(exampleValue)); // case - a complicated graph of an List inside a Map. Immutable references should stay // but all List and Map instances should point to different objects. // A mixed map of array and immutable elements shouldn't happen in ElasticSearch // but we'll check this case anyway. String listValueNo1 = "listVal1"; String listValueNo2 = "listVal2"; String mapValueNo1 = "mapVal1"; String mapValueNo2 = "mapVal2"; String mapKeyNo1 = "key1"; String mapKeyNo2 = "key2"; String mapListKey = "list"; List<String> list = new LinkedList<String>(); list.add(listValueNo1); list.add(listValueNo2); Map<String, Object> map = new LinkedHashMap<String, Object>(); map.put(mapKeyNo1, mapValueNo1); map.put(mapKeyNo2, mapValueNo2); map.put(mapListKey, list); Object copiedMapObj = StructureUtils.getADeepStructureCopy(map); // The Map should be of the same size but different instance Assert.assertTrue(copiedMapObj instanceof Map); Map<String, Object> copiedMap = (Map<String, Object>) copiedMapObj; Assert.assertTrue(map.size() == copiedMap.size()); Assert.assertNotSame(map, copiedMapObj); // The List should be of the same size but different instance. Object copiedListObj = copiedMap.get(mapListKey); Assert.assertTrue(copiedListObj instanceof List); List<Object> copiedList = (List<Object>) copiedListObj; Assert.assertNotSame(copiedList, list); // All immutable values inside the List should be same objects. Assert.assertTrue(copiedList.contains(listValueNo1)); Assert.assertTrue(copiedList.contains(listValueNo2)); } }