/*
* Copyright 2016 ThoughtWorks, 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 com.thoughtworks.studios.shine.cruise.stage.details;
import com.thoughtworks.go.domain.StageIdentifier;
import com.thoughtworks.studios.shine.cruise.GoIntegrationException;
import com.thoughtworks.studios.shine.cruise.GoOntology;
import com.thoughtworks.studios.shine.semweb.Graph;
import com.thoughtworks.studios.shine.semweb.TempGraphFactory;
import com.thoughtworks.studios.shine.semweb.grddl.XSLTTransformerRegistry;
import com.thoughtworks.studios.shine.semweb.sesame.InMemoryTempGraphFactory;
import com.thoughtworks.studios.shine.xunit.XUnitOntology;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.util.concurrent.Semaphore;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.junit.Assert.*;
public class LazyStageGraphLoaderTest {
private StageStorage stageStorage;
private InMemoryTempGraphFactory graphFactory;
@Before
public void initStageStorage() {
stageStorage = new StageStorage(new File(System.getProperty("java.io.tmpdir"), "shine").getAbsolutePath());
stageStorage.clear();
graphFactory = new InMemoryTempGraphFactory();
}
@Test
public void directLoadFromStageStorageIfStageAlreadyStored() {
Graph stageGraph = graphFactory.createTempGraph();
stageGraph.addTriplesFromTurtle("" +
"@prefix cruise: <" + GoOntology.URI + "> . " +
"@prefix xunit: <" + XUnitOntology.URI + "> . " +
"@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . " +
"@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . " +
"" +
" <http://pipeline/1> a cruise:Pipeline . " +
" <http://pipeline/1> cruise:pipelineName \"pipeline-foo\"^^xsd:string ." +
" <http://pipeline/1> cruise:pipelineCounter \"23\"^^xsd:integer . " +
" <http://pipeline/1> cruise:hasStage <http://stage/1> . " +
" <http://stage/1> a cruise:Stage . " +
" <http://stage/1> cruise:stageName \"stage-1\"^^xsd:string . " +
" <http://stage/1> cruise:stageCounter \"1\"^^xsd:integer . " +
"");
stageStorage.save(stageGraph);
LazyStageGraphLoader loader = new LazyStageGraphLoader(null, stageStorage);
Graph loadedStageGraph = loader.load(new StageIdentifier("pipeline-foo", 23, "stage-1", "1"));
assertTrue(loadedStageGraph.containsResourceWithURI("http://stage/1"));
}
@Test
public void loadsFromRealLoaderAndSavesToStorageWhenNotAlreadyStoried() {
StageIdentifier stageId = new StageIdentifier("pipeline-foo", 23, "stage-1", "1");
DummyStageResourceImporter realLoader = new DummyStageResourceImporter(realGraph(), stageId);
LazyStageGraphLoader loader = new LazyStageGraphLoader(realLoader, stageStorage);
Graph stageGraph = loader.load(stageId);
assertTrue(stageGraph.containsResourceWithURI("http://stage/1"));
assertTrue(stageStorage.isStageStored(stageId));
}
private Graph realGraph() {
final Graph realStageGraph = graphFactory.createTempGraph();
realStageGraph.addTriplesFromTurtle("" +
"@prefix cruise: <" + GoOntology.URI + "> . " +
"@prefix xunit: <" + XUnitOntology.URI + "> . " +
"@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . " +
"@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . " +
"" +
" <http://pipeline/1> a cruise:Pipeline . " +
" <http://pipeline/1> cruise:pipelineName \"pipeline-foo\"^^xsd:string ." +
" <http://pipeline/1> cruise:pipelineCounter \"23\"^^xsd:integer . " +
" <http://pipeline/1> cruise:hasStage <http://stage/1> . " +
" <http://stage/1> a cruise:Stage . " +
" <http://stage/1> cruise:stageName \"stage-1\"^^xsd:string . " +
" <http://stage/1> cruise:stageCounter \"1\"^^xsd:integer . " +
" <http://stage/1> cruise:hasJob <http://job/1> . " + // only job in the stage graph
"");
return realStageGraph;
}
@Test
public void shouldReuseTransformerAcrossSerialInvocations() {
StageIdentifier stageId = new StageIdentifier("pipeline-foo", 23, "stage-1", "1");
DummyStageResourceImporter realLoader = new DummyStageResourceImporter(realGraph(), stageId, new Semaphore(2));
LazyStageGraphLoader loader = new LazyStageGraphLoader(realLoader, stageStorage);
loader.load(stageId);
XSLTTransformerRegistry transformerRegistryFromFirstLoad = realLoader.transformerRegistry;
stageStorage.clear();
loader.load(stageId);
XSLTTransformerRegistry transformerRegistryFromSecondLoad = realLoader.transformerRegistry;
assertThat(transformerRegistryFromFirstLoad, sameInstance(transformerRegistryFromSecondLoad));
}
class DummyStageResourceImporter extends StageResourceImporter {
private Graph importedStageGraph;
private StageIdentifier expectedStageId;
private Semaphore semaphore;
private XSLTTransformerRegistry transformerRegistry;
DummyStageResourceImporter(Graph importedStageGraph, StageIdentifier stageId) {
this(importedStageGraph, stageId, new Semaphore(1));
}
DummyStageResourceImporter(Graph importedStageGraph, StageIdentifier stageId, Semaphore semaphore) {
super((String) null, null, null, null,null);
this.importedStageGraph = importedStageGraph;
this.expectedStageId = stageId;
this.semaphore = semaphore;
}
@Override public Graph load(StageIdentifier stageIdentifier, TempGraphFactory tempGraphFactory, final XSLTTransformerRegistry transformerRegistry) throws GoIntegrationException {
this.transformerRegistry = transformerRegistry;
try {
semaphore.acquire();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
assertEquals(expectedStageId, stageIdentifier);
return importedStageGraph;
}
}
}