Java tutorial
/* * Copyright 2016, Yahoo Inc. * Licensed under the terms of the Apache License, Version 2.0. * See the LICENSE file associated with the project for terms. */ package com.yahoo.bullet.parsing; import com.yahoo.bullet.BulletConfig; import com.yahoo.bullet.operations.AggregationOperations.AggregationType; import com.yahoo.bullet.operations.FilterOperations.FilterType; import com.yahoo.bullet.operations.aggregations.Strategy; import com.yahoo.bullet.record.BulletRecord; import com.yahoo.bullet.result.Clip; import com.yahoo.bullet.result.Metadata; import com.yahoo.bullet.result.RecordBox; import org.apache.commons.lang3.tuple.Pair; import org.testng.Assert; import org.testng.annotations.Test; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class SpecificationTest { private class FailingStrategy implements Strategy { public int consumptionFailure = 0; public int combiningFailure = 0; public int serializingFailure = 0; public int aggregationFailure = 0; @Override public void consume(BulletRecord data) { consumptionFailure++; throw new RuntimeException("Consuming record test failure"); } @Override public void combine(byte[] serializedAggregation) { combiningFailure++; throw new RuntimeException("Combining serialized aggregation test failure"); } @Override public byte[] getSerializedAggregation() { serializingFailure++; throw new RuntimeException("Serializing aggregation test failure"); } @Override public Clip getAggregation() { aggregationFailure++; throw new RuntimeException("Getting aggregation test failure"); } } public static Stream<BulletRecord> makeStream(int count) { return IntStream.range(0, count).mapToObj(x -> RecordBox.get().getRecord()); } public static ArrayList<BulletRecord> makeList(int count) { return makeStream(count).collect(Collectors.toCollection(ArrayList::new)); } public static int size(BulletRecord record) { int size = 0; for (Object ignored : record) { size++; } return size; } @Test public void testDefaults() { Specification specification = new Specification(); specification.configure(emptyMap()); Assert.assertNull(specification.getProjection()); Assert.assertNull(specification.getFilters()); Assert.assertEquals(specification.getDuration(), Specification.DEFAULT_DURATION_MS); Assert.assertEquals(specification.getAggregation().getType(), AggregationType.RAW); Assert.assertEquals(specification.getAggregation().getSize(), Aggregation.DEFAULT_SIZE); Assert.assertTrue(specification.isAcceptingData()); Assert.assertEquals(specification.getAggregate().getRecords(), emptyList()); } @Test public void testExtractField() { BulletRecord record = RecordBox.get().add("field", "foo").add("map_field.foo", "bar") .addMap("map_field", Pair.of("foo", "baz")).addList("list_field", singletonMap("foo", "baz")) .getRecord(); Assert.assertNull(Specification.extractField(null, record)); Assert.assertNull(Specification.extractField("", record)); Assert.assertNull(Specification.extractField("id", record)); Assert.assertEquals(Specification.extractField("map_field.foo", record), "baz"); Assert.assertNull(Specification.extractField("list_field.bar", record)); } @Test public void testAggregationForced() { Specification specification = new Specification(); specification.setAggregation(null); Assert.assertNull(specification.getProjection()); Assert.assertNull(specification.getFilters()); // If you had null for aggregation Assert.assertNull(specification.getAggregation()); specification.configure(Collections.emptyMap()); Assert.assertTrue(specification.isAcceptingData()); Assert.assertEquals(specification.getAggregate().getRecords(), emptyList()); } @Test public void testDuration() { Specification specification = new Specification(); specification.configure(emptyMap()); Assert.assertEquals(specification.getDuration(), specification.DEFAULT_DURATION_MS); specification.setDuration(-1000); specification.configure(emptyMap()); Assert.assertEquals(specification.getDuration(), specification.DEFAULT_DURATION_MS); specification.setDuration(0); specification.configure(emptyMap()); Assert.assertEquals(specification.getDuration(), (Integer) 0); specification.setDuration(1); specification.configure(emptyMap()); Assert.assertEquals(specification.getDuration(), (Integer) 1); specification.setDuration(Specification.DEFAULT_DURATION_MS); specification.configure(emptyMap()); Assert.assertEquals(specification.getDuration(), Specification.DEFAULT_DURATION_MS); specification.setDuration(Specification.DEFAULT_MAX_DURATION_MS); specification.configure(emptyMap()); Assert.assertEquals(specification.getDuration(), Specification.DEFAULT_MAX_DURATION_MS); specification.setDuration(Specification.DEFAULT_MAX_DURATION_MS * 2); specification.configure(emptyMap()); Assert.assertEquals(specification.getDuration(), Specification.DEFAULT_MAX_DURATION_MS); } @Test public void testCustomDuration() { Map<String, Object> config = new HashMap<>(); config.put(BulletConfig.SPECIFICATION_DEFAULT_DURATION, 200); config.put(BulletConfig.SPECIFICATION_MAX_DURATION, 1000); Specification specification = new Specification(); specification.setDuration(null); specification.configure(config); Assert.assertEquals(specification.getDuration(), (Integer) 200); specification.setDuration(-1000); specification.configure(config); Assert.assertEquals(specification.getDuration(), (Integer) 200); specification.setDuration(0); specification.configure(config); Assert.assertEquals(specification.getDuration(), (Integer) 0); specification.setDuration(1); specification.configure(config); Assert.assertEquals(specification.getDuration(), (Integer) 1); specification.setDuration(200); specification.configure(config); Assert.assertEquals(specification.getDuration(), (Integer) 200); specification.setDuration(1000); specification.configure(config); Assert.assertEquals(specification.getDuration(), (Integer) 1000); specification.setDuration(2000); specification.configure(config); Assert.assertEquals(specification.getDuration(), (Integer) 1000); } @Test public void testFiltering() { Specification specification = new Specification(); specification.setFilters(singletonList(FilterClauseTest.getFieldFilter(FilterType.EQUALS, "foo", "bar"))); specification.configure(emptyMap()); Assert.assertTrue(specification.filter(RecordBox.get().add("field", "foo").getRecord())); Assert.assertTrue(specification.filter(RecordBox.get().add("field", "bar").getRecord())); Assert.assertFalse(specification.filter(RecordBox.get().add("field", "baz").getRecord())); } @Test public void testReceiveTimestampNoProjection() { Long start = System.currentTimeMillis(); Map<String, Object> config = new HashMap<>(); config.put(BulletConfig.RECORD_INJECT_TIMESTAMP, true); Specification specification = new Specification(); specification.setProjection(null); specification.configure(config); BulletRecord input = RecordBox.get().add("field", "foo").add("mid", "123").getRecord(); BulletRecord actual = specification.project(input); Long end = System.currentTimeMillis(); Assert.assertEquals(size(actual), 3); Assert.assertEquals(actual.get("field"), "foo"); Assert.assertEquals(actual.get("mid"), "123"); Long recordedTimestamp = (Long) actual.get(Specification.DEFAULT_RECEIVE_TIMESTAMP_KEY); Assert.assertTrue(recordedTimestamp >= start); Assert.assertTrue(recordedTimestamp <= end); } @Test public void testReceiveTimestamp() { Long start = System.currentTimeMillis(); Map<String, Object> config = new HashMap<>(); config.put(BulletConfig.RECORD_INJECT_TIMESTAMP, true); Specification specification = new Specification(); Projection projection = new Projection(); projection.setFields(singletonMap("field", "bid")); specification.setProjection(projection); specification.configure(config); BulletRecord input = RecordBox.get().add("field", "foo").add("mid", "123").getRecord(); BulletRecord actual = specification.project(input); Long end = System.currentTimeMillis(); Assert.assertEquals(size(actual), 2); Assert.assertEquals(actual.get("bid"), "foo"); Long recordedTimestamp = (Long) actual.get(Specification.DEFAULT_RECEIVE_TIMESTAMP_KEY); Assert.assertTrue(recordedTimestamp >= start); Assert.assertTrue(recordedTimestamp <= end); } @Test public void testAggregationDefault() { Specification specification = new Specification(); Aggregation aggregation = new Aggregation(); aggregation.setType(null); aggregation.setSize(Aggregation.DEFAULT_MAX_SIZE - 1); specification.setAggregation(aggregation); Assert.assertNull(aggregation.getType()); specification.configure(emptyMap()); // Specification no longer fixes type Assert.assertNull(aggregation.getType()); Assert.assertEquals(aggregation.getSize(), new Integer(Aggregation.DEFAULT_MAX_SIZE - 1)); } @Test public void testMeetingDefaultSpecification() { Specification specification = new Specification(); specification.configure(emptyMap()); Assert.assertTrue(makeStream(Aggregation.DEFAULT_SIZE - 1).map(specification::filter).allMatch(x -> x)); // Check that we only get the default number out makeList(Aggregation.DEFAULT_SIZE + 2).forEach(specification::aggregate); Assert.assertEquals((Integer) specification.getAggregate().getRecords().size(), Aggregation.DEFAULT_SIZE); } @Test public void testValidate() { Specification specification = new Specification(); Aggregation mockAggregation = mock(Aggregation.class); Optional<List<Error>> aggregationErrors = Optional .of(asList(Error.of("foo", new ArrayList<>()), Error.of("bar", new ArrayList<>()))); when(mockAggregation.validate()).thenReturn(aggregationErrors); specification.setAggregation(mockAggregation); Clause mockClauseA = mock(Clause.class); Clause mockClauseB = mock(Clause.class); when(mockClauseA.validate()).thenReturn(Optional.of(singletonList(Error.of("baz", new ArrayList<>())))); when(mockClauseB.validate()).thenReturn(Optional.of(singletonList(Error.of("qux", new ArrayList<>())))); specification.setFilters(asList(mockClauseA, mockClauseB)); Projection mockProjection = mock(Projection.class); when(mockProjection.validate()).thenReturn(Optional.of(singletonList(Error.of("quux", new ArrayList<>())))); specification.setProjection(mockProjection); Optional<List<Error>> errorList = specification.validate(); Assert.assertTrue(errorList.isPresent()); Assert.assertEquals(errorList.get().size(), 5); } @Test public void testValidateNullValues() { Specification specification = new Specification(); specification.setProjection(null); specification.setFilters(null); specification.setAggregation(null); Optional<List<Error>> errorList = specification.validate(); Assert.assertFalse(errorList.isPresent()); } @Test public void testAggregationExceptions() { Aggregation aggregation = mock(Aggregation.class); FailingStrategy failure = new FailingStrategy(); when(aggregation.getStrategy()).thenReturn(failure); Specification specification = new Specification(); specification.setAggregation(aggregation); ; specification.aggregate(RecordBox.get().getRecord()); specification.aggregate(new byte[0]); Assert.assertNull(specification.getSerializedAggregate()); Clip actual = specification.getAggregate(); Assert.assertNotNull(actual.getMeta()); Assert.assertEquals(actual.getRecords().size(), 0); Map<String, Object> actualMeta = actual.getMeta().asMap(); Assert.assertEquals(actualMeta.size(), 1); Assert.assertNotNull(actualMeta.get(Metadata.ERROR_KEY)); Error expectedError = Error.makeError("Getting aggregation test failure", Specification.AGGREGATION_FAILURE_RESOLUTION); Assert.assertEquals(actualMeta.get(Metadata.ERROR_KEY), singletonList(expectedError)); Assert.assertEquals(failure.consumptionFailure, 1); Assert.assertEquals(failure.combiningFailure, 1); Assert.assertEquals(failure.serializingFailure, 1); Assert.assertEquals(failure.aggregationFailure, 1); } @Test public void testToString() { Specification specification = new Specification(); specification.configure(emptyMap()); Assert.assertEquals(specification.toString(), "{filters: null, projection: null, " + "aggregation: {size: 1, type: RAW, fields: null, attributes: null}, duration: 30000}"); specification.setFilters(singletonList(FilterClauseTest.getFieldFilter(FilterType.EQUALS, "foo", "bar"))); Projection projection = new Projection(); projection.setFields(singletonMap("field", "bid")); specification.setProjection(projection); specification.configure(emptyMap()); Assert.assertEquals(specification.toString(), "{filters: [{operation: EQUALS, field: field, values: [foo, bar]}], " + "projection: {fields: {field=bid}}, " + "aggregation: {size: 1, type: RAW, fields: null, attributes: null}, duration: 30000}"); } }