/* * Copyright © 2015 Cask Data, Inc. * * Licensed 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 co.cask.cdap.data2.metadata.writer; import co.cask.cdap.api.dataset.module.DatasetDefinitionRegistry; import co.cask.cdap.common.app.RunIds; import co.cask.cdap.data.runtime.DataSetsModules; import co.cask.cdap.data2.dataset2.DatasetDefinitionRegistryFactory; import co.cask.cdap.data2.dataset2.DatasetFramework; import co.cask.cdap.data2.dataset2.DatasetFrameworkTestUtil; import co.cask.cdap.data2.dataset2.DefaultDatasetDefinitionRegistry; import co.cask.cdap.data2.dataset2.InMemoryDatasetFramework; import co.cask.cdap.data2.metadata.lineage.AccessType; import co.cask.cdap.data2.metadata.lineage.LineageStore; import co.cask.cdap.data2.metadata.publisher.MetadataChangePublisher; import co.cask.cdap.data2.metadata.publisher.NoOpMetadataChangePublisher; import co.cask.cdap.data2.metadata.store.DefaultMetadataStore; import co.cask.cdap.data2.metadata.store.MetadataStore; import co.cask.cdap.proto.Id; import co.cask.cdap.proto.ProgramType; import co.cask.cdap.proto.metadata.MetadataScope; import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; import com.google.inject.Injector; import com.google.inject.assistedinject.FactoryModuleBuilder; import com.google.inject.name.Names; import org.junit.Assert; import org.junit.ClassRule; import org.junit.Test; import java.util.concurrent.TimeUnit; /** * Tests BasicLineageWriter */ public class BasicLineageWriterTest { @ClassRule public static DatasetFrameworkTestUtil dsFrameworkUtil = new DatasetFrameworkTestUtil(); @Test public void testWrites() throws Exception { Injector injector = getInjector(); MetadataStore metadataStore = injector.getInstance(MetadataStore.class); LineageStore lineageStore = injector.getInstance(LineageStore.class); LineageWriter lineageWriter = new BasicLineageWriter(lineageStore); // Define entities Id.Program program = Id.Program.from("default", "app", ProgramType.FLOW, "flow"); Id.Stream stream = Id.Stream.from("default", "stream"); Id.Run run1 = new Id.Run(program, RunIds.generate(10000).getId()); Id.Run run2 = new Id.Run(program, RunIds.generate(20000).getId()); // Tag stream metadataStore.addTags(MetadataScope.USER, stream, "stag1", "stag2"); // Write access for run1 lineageWriter.addAccess(run1, stream, AccessType.READ); Assert.assertEquals(ImmutableSet.of(program, stream), lineageStore.getEntitiesForRun(run1)); // Record time to verify duplicate writes. long beforeSecondTag = System.currentTimeMillis(); // Wait for next millisecond, since access time is stored in milliseconds. TimeUnit.MILLISECONDS.sleep(1); // Add another tag to stream metadataStore.addTags(MetadataScope.USER, stream, "stag3"); // Write access for run1 again lineageWriter.addAccess(run1, stream, AccessType.READ); // The write should be no-op, and access time for run1 should not be updated Assert.assertTrue(lineageStore.getAccessTimesForRun(run1).get(0) < beforeSecondTag); // However, you can write access for another run lineageWriter.addAccess(run2, stream, AccessType.READ); // Assert new access time is written Assert.assertTrue(lineageStore.getAccessTimesForRun(run2).get(0) >= beforeSecondTag); } private static Injector getInjector() { return dsFrameworkUtil.getInjector().createChildInjector( new AbstractModule() { @Override protected void configure() { install(new FactoryModuleBuilder() .implement(DatasetDefinitionRegistry.class, DefaultDatasetDefinitionRegistry.class) .build(DatasetDefinitionRegistryFactory.class)); bind(DatasetFramework.class) .annotatedWith(Names.named(DataSetsModules.BASIC_DATASET_FRAMEWORK)) .to(InMemoryDatasetFramework.class); bind(MetadataChangePublisher.class).to(NoOpMetadataChangePublisher.class); bind(MetadataStore.class).to(DefaultMetadataStore.class); } } ); } }