| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.hadoop.yarn.api.records.timelineservice; |
| |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; |
| import org.apache.hadoop.yarn.api.records.ApplicationId; |
| import org.apache.hadoop.yarn.api.records.ContainerId; |
| import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; |
| import org.apache.hadoop.yarn.util.timeline.TimelineUtils; |
| import org.junit.Test; |
| import org.junit.Assert; |
| |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| /** |
| * Tests timeline service API records. |
| */ |
| public class TestTimelineServiceRecords { |
| private static final Log LOG = |
| LogFactory.getLog(TestTimelineServiceRecords.class); |
| |
| @Test |
| public void testTimelineEntities() throws Exception { |
| TimelineEntity entity = new TimelineEntity(); |
| entity.setType("test type 1"); |
| entity.setId("test id 1"); |
| entity.addInfo("test info key 1", "test info value 1"); |
| entity.addInfo("test info key 2", |
| Arrays.asList("test info value 2", "test info value 3")); |
| entity.addInfo("test info key 3", true); |
| Assert.assertTrue( |
| entity.getInfo().get("test info key 3") instanceof Boolean); |
| entity.addConfig("test config key 1", "test config value 1"); |
| entity.addConfig("test config key 2", "test config value 2"); |
| |
| TimelineMetric metric1 = |
| new TimelineMetric(TimelineMetric.Type.TIME_SERIES); |
| metric1.setId("test metric id 1"); |
| metric1.addValue(1L, 1.0F); |
| metric1.addValue(3L, 3.0D); |
| metric1.addValue(2L, 2); |
| Assert.assertEquals(TimelineMetric.Type.TIME_SERIES, metric1.getType()); |
| Iterator<Map.Entry<Long, Number>> itr = |
| metric1.getValues().entrySet().iterator(); |
| Map.Entry<Long, Number> entry = itr.next(); |
| Assert.assertEquals(new Long(3L), entry.getKey()); |
| Assert.assertEquals(3.0D, entry.getValue()); |
| entry = itr.next(); |
| Assert.assertEquals(new Long(2L), entry.getKey()); |
| Assert.assertEquals(2, entry.getValue()); |
| entry = itr.next(); |
| Assert.assertEquals(new Long(1L), entry.getKey()); |
| Assert.assertEquals(1.0F, entry.getValue()); |
| Assert.assertFalse(itr.hasNext()); |
| entity.addMetric(metric1); |
| |
| TimelineMetric metric2 = |
| new TimelineMetric(TimelineMetric.Type.SINGLE_VALUE); |
| metric2.setId("test metric id 1"); |
| metric2.addValue(3L, (short) 3); |
| Assert.assertEquals(TimelineMetric.Type.SINGLE_VALUE, metric2.getType()); |
| Assert.assertTrue( |
| metric2.getValues().values().iterator().next() instanceof Short); |
| Map<Long, Number> points = new HashMap<>(); |
| points.put(4L, 4.0D); |
| points.put(5L, 5.0D); |
| try { |
| metric2.setValues(points); |
| Assert.fail(); |
| } catch (IllegalArgumentException e) { |
| Assert.assertTrue(e.getMessage().contains( |
| "Values cannot contain more than one point in")); |
| } |
| try { |
| metric2.addValues(points); |
| Assert.fail(); |
| } catch (IllegalArgumentException e) { |
| Assert.assertTrue(e.getMessage().contains( |
| "Values cannot contain more than one point in")); |
| } |
| entity.addMetric(metric2); |
| |
| TimelineMetric metric3 = |
| new TimelineMetric(TimelineMetric.Type.SINGLE_VALUE); |
| metric3.setId("test metric id 1"); |
| metric3.addValue(4L, (short) 4); |
| Assert.assertEquals("metric3 should equal to metric2! ", metric3, metric2); |
| Assert.assertNotEquals("metric1 should not equal to metric2! ", |
| metric1, metric2); |
| |
| TimelineEvent event1 = new TimelineEvent(); |
| event1.setId("test event id 1"); |
| event1.addInfo("test info key 1", "test info value 1"); |
| event1.addInfo("test info key 2", |
| Arrays.asList("test info value 2", "test info value 3")); |
| event1.addInfo("test info key 3", true); |
| Assert.assertTrue( |
| event1.getInfo().get("test info key 3") instanceof Boolean); |
| event1.setTimestamp(1L); |
| entity.addEvent(event1); |
| |
| TimelineEvent event2 = new TimelineEvent(); |
| event2.setId("test event id 2"); |
| event2.addInfo("test info key 1", "test info value 1"); |
| event2.addInfo("test info key 2", |
| Arrays.asList("test info value 2", "test info value 3")); |
| event2.addInfo("test info key 3", true); |
| Assert.assertTrue( |
| event2.getInfo().get("test info key 3") instanceof Boolean); |
| event2.setTimestamp(2L); |
| entity.addEvent(event2); |
| |
| Assert.assertFalse("event1 should not equal to event2! ", |
| event1.equals(event2)); |
| TimelineEvent event3 = new TimelineEvent(); |
| event3.setId("test event id 1"); |
| event3.setTimestamp(1L); |
| Assert.assertEquals("event1 should equal to event3! ", event3, event1); |
| Assert.assertNotEquals("event1 should not equal to event2! ", |
| event1, event2); |
| |
| entity.setCreatedTime(0L); |
| entity.addRelatesToEntity("test type 2", "test id 2"); |
| entity.addRelatesToEntity("test type 3", "test id 3"); |
| entity.addIsRelatedToEntity("test type 4", "test id 4"); |
| entity.addIsRelatedToEntity("test type 5", "test id 5"); |
| LOG.info(TimelineUtils.dumpTimelineRecordtoJSON(entity, true)); |
| |
| TimelineEntities entities = new TimelineEntities(); |
| TimelineEntity entity1 = new TimelineEntity(); |
| entities.addEntity(entity1); |
| TimelineEntity entity2 = new TimelineEntity(); |
| entities.addEntity(entity2); |
| LOG.info(TimelineUtils.dumpTimelineRecordtoJSON(entities, true)); |
| |
| Assert.assertFalse("entity 1 should not be valid without type and id", |
| entity1.isValid()); |
| entity1.setId("test id 2"); |
| entity1.setType("test type 2"); |
| entity2.setId("test id 1"); |
| entity2.setType("test type 1"); |
| |
| Assert.assertEquals("Timeline entity should equal to entity2! ", |
| entity, entity2); |
| Assert.assertNotEquals("entity1 should not equal to entity! ", |
| entity1, entity); |
| Assert.assertEquals("entity should be less than entity1! ", |
| entity1.compareTo(entity), 1); |
| Assert.assertEquals("entity's hash code should be -28727840 but not " |
| + entity.hashCode(), entity.hashCode(), -28727840); |
| } |
| |
| @Test |
| public void testFirstClassCitizenEntities() throws Exception { |
| UserEntity user = new UserEntity(); |
| user.setId("test user id"); |
| |
| QueueEntity queue = new QueueEntity(); |
| queue.setId("test queue id"); |
| |
| |
| ClusterEntity cluster = new ClusterEntity(); |
| cluster.setId("test cluster id"); |
| |
| FlowRunEntity flow1 = new FlowRunEntity(); |
| //flow1.setId("test flow id 1"); |
| flow1.setUser(user.getId()); |
| flow1.setName("test flow name 1"); |
| flow1.setVersion("test flow version 1"); |
| flow1.setRunId(1L); |
| |
| FlowRunEntity flow2 = new FlowRunEntity(); |
| //flow2.setId("test flow run id 2"); |
| flow2.setUser(user.getId()); |
| flow2.setName("test flow name 2"); |
| flow2.setVersion("test flow version 2"); |
| flow2.setRunId(2L); |
| |
| ApplicationEntity app1 = new ApplicationEntity(); |
| app1.setId(ApplicationId.newInstance(0, 1).toString()); |
| app1.setQueue(queue.getId()); |
| |
| ApplicationEntity app2 = new ApplicationEntity(); |
| app2.setId(ApplicationId.newInstance(0, 2).toString()); |
| app2.setQueue(queue.getId()); |
| |
| ApplicationAttemptEntity appAttempt = new ApplicationAttemptEntity(); |
| appAttempt.setId(ApplicationAttemptId.newInstance( |
| ApplicationId.newInstance(0, 1), 1).toString()); |
| |
| ContainerEntity container = new ContainerEntity(); |
| container.setId(ContainerId.newContainerId( |
| ApplicationAttemptId.newInstance( |
| ApplicationId.newInstance(0, 1), 1), 1).toString()); |
| |
| cluster.addChild(TimelineEntityType.YARN_FLOW_RUN.toString(), |
| flow1.getId()); |
| flow1 |
| .setParent(TimelineEntityType.YARN_CLUSTER.toString(), cluster.getId()); |
| flow1.addChild(TimelineEntityType.YARN_FLOW_RUN.toString(), flow2.getId()); |
| flow2.setParent(TimelineEntityType.YARN_FLOW_RUN.toString(), flow1.getId()); |
| flow2.addChild(TimelineEntityType.YARN_APPLICATION.toString(), |
| app1.getId()); |
| flow2.addChild(TimelineEntityType.YARN_APPLICATION.toString(), |
| app2.getId()); |
| app1.setParent(TimelineEntityType.YARN_FLOW_RUN.toString(), flow2.getId()); |
| app1.addChild(TimelineEntityType.YARN_APPLICATION_ATTEMPT.toString(), |
| appAttempt.getId()); |
| appAttempt |
| .setParent(TimelineEntityType.YARN_APPLICATION.toString(), |
| app1.getId()); |
| app2.setParent(TimelineEntityType.YARN_FLOW_RUN.toString(), flow2.getId()); |
| appAttempt.addChild(TimelineEntityType.YARN_CONTAINER.toString(), |
| container.getId()); |
| container.setParent(TimelineEntityType.YARN_APPLICATION_ATTEMPT.toString(), |
| appAttempt.getId()); |
| |
| LOG.info(TimelineUtils.dumpTimelineRecordtoJSON(cluster, true)); |
| LOG.info(TimelineUtils.dumpTimelineRecordtoJSON(flow1, true)); |
| LOG.info(TimelineUtils.dumpTimelineRecordtoJSON(flow2, true)); |
| LOG.info(TimelineUtils.dumpTimelineRecordtoJSON(app1, true)); |
| LOG.info(TimelineUtils.dumpTimelineRecordtoJSON(app2, true)); |
| LOG.info(TimelineUtils.dumpTimelineRecordtoJSON(appAttempt, true)); |
| LOG.info(TimelineUtils.dumpTimelineRecordtoJSON(container, true)); |
| |
| |
| // Check parent/children APIs |
| Assert.assertNotNull(app1.getParent()); |
| Assert.assertEquals(flow2.getType(), app1.getParent().getType()); |
| Assert.assertEquals(flow2.getId(), app1.getParent().getId()); |
| app1.addInfo(ApplicationEntity.PARENT_INFO_KEY, "invalid parent object"); |
| try { |
| app1.getParent(); |
| Assert.fail(); |
| } catch (Exception e) { |
| Assert.assertTrue(e instanceof YarnRuntimeException); |
| Assert.assertTrue(e.getMessage().contains( |
| "Parent info is invalid identifier object")); |
| } |
| |
| Assert.assertNotNull(app1.getChildren()); |
| Assert.assertEquals(1, app1.getChildren().size()); |
| Assert.assertEquals( |
| appAttempt.getType(), app1.getChildren().iterator().next().getType()); |
| Assert.assertEquals( |
| appAttempt.getId(), app1.getChildren().iterator().next().getId()); |
| app1.addInfo(ApplicationEntity.CHILDREN_INFO_KEY, |
| Collections.singletonList("invalid children set")); |
| try { |
| app1.getChildren(); |
| Assert.fail(); |
| } catch (Exception e) { |
| Assert.assertTrue(e instanceof YarnRuntimeException); |
| Assert.assertTrue(e.getMessage().contains( |
| "Children info is invalid identifier set")); |
| } |
| app1.addInfo(ApplicationEntity.CHILDREN_INFO_KEY, |
| Collections.singleton("invalid child object")); |
| try { |
| app1.getChildren(); |
| Assert.fail(); |
| } catch (Exception e) { |
| Assert.assertTrue(e instanceof YarnRuntimeException); |
| Assert.assertTrue(e.getMessage().contains( |
| "Children info contains invalid identifier object")); |
| } |
| } |
| |
| @Test |
| public void testUser() throws Exception { |
| UserEntity user = new UserEntity(); |
| user.setId("test user id"); |
| user.addInfo("test info key 1", "test info value 1"); |
| user.addInfo("test info key 2", "test info value 2"); |
| LOG.info(TimelineUtils.dumpTimelineRecordtoJSON(user, true)); |
| } |
| |
| @Test |
| public void testQueue() throws Exception { |
| QueueEntity queue = new QueueEntity(); |
| queue.setId("test queue id"); |
| queue.addInfo("test info key 1", "test info value 1"); |
| queue.addInfo("test info key 2", "test info value 2"); |
| queue.setParent(TimelineEntityType.YARN_QUEUE.toString(), |
| "test parent queue id"); |
| queue.addChild(TimelineEntityType.YARN_QUEUE.toString(), |
| "test child queue id 1"); |
| queue.addChild(TimelineEntityType.YARN_QUEUE.toString(), |
| "test child queue id 2"); |
| LOG.info(TimelineUtils.dumpTimelineRecordtoJSON(queue, true)); |
| } |
| } |