/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* 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 org.guvnor.common.services.backend.metadata;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.guvnor.common.services.backend.metadata.attribute.DiscussionView;
import org.guvnor.common.services.backend.metadata.attribute.GeneratedFileAttributes;
import org.guvnor.common.services.backend.metadata.attribute.GeneratedAttributesView;
import org.guvnor.common.services.backend.metadata.attribute.OtherMetaView;
import org.guvnor.common.services.shared.metadata.model.Metadata;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.uberfire.io.IOService;
import org.uberfire.io.attribute.DublinCoreView;
import org.uberfire.java.nio.base.version.VersionAttributeView;
import org.uberfire.java.nio.base.version.VersionAttributes;
import org.uberfire.java.nio.base.version.VersionRecord;
import org.uberfire.java.nio.file.NoSuchFileException;
import org.uberfire.java.nio.file.Path;
import org.uberfire.java.nio.file.api.FileSystemProviders;
import org.uberfire.java.nio.fs.file.SimpleFileSystemProvider;
import org.uberfire.rpc.SessionInfo;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class MetadataCreatorTest {
private SimpleFileSystemProvider fileSystemProvider;
@Mock
private IOService configIOService;
@Mock
private SessionInfo sessionInfo;
@Mock
private DublinCoreView dcoreView;
@Mock
private DiscussionView discussView;
@Mock
private OtherMetaView otherMetaView;
@Mock
private VersionAttributeView versionAttributeView;
@Mock
private GeneratedFileAttributes generatedFileAttributes;
@Mock
private GeneratedAttributesView generatedAttributesView;
private MetadataCreator service;
private Path mainFilePath;
private ArrayList<VersionRecord> versionRecords;
@Before
public void setUp() throws Exception {
versionRecords = new ArrayList<VersionRecord>();
versionRecords.add( createVersionRecord() );
VersionAttributes versionAttributes = new VersionAttributesMock( versionRecords );
when( versionAttributeView.readAttributes() ).thenReturn( versionAttributes );
when( dcoreView.readAttributes() ).thenReturn( new DublinCoreAttributesMock() );
when( otherMetaView.readAttributes() ).thenReturn( new OtherMetaAttributesMock() );
when( discussView.readAttributes() ).thenReturn( new DiscussionAttributesMock() );
when( generatedAttributesView.readAttributes() ).thenReturn( generatedFileAttributes );
fileSystemProvider = new SimpleFileSystemProvider();
//Ensure URLs use the default:// scheme
fileSystemProvider.forceAsDefault();
mainFilePath = fileSystemProvider.getPath( this.getClass().getResource( "myfile.file" ).toURI() );
service = new MetadataCreator( mainFilePath,
configIOService,
sessionInfo,
dcoreView,
discussView,
otherMetaView,
versionAttributeView,
generatedAttributesView );
}
@Test
public void testSimple() throws Exception {
Metadata metadata = service.create();
assertNotNull( metadata );
assertNotNull( metadata.getTags() );
assertNotNull( metadata.getDiscussion() );
assertNotNull( metadata.getVersion() );
}
@Test
public void testGeneratedAttributes() {
when( generatedFileAttributes.isGenerated() ).thenReturn( true );
when( generatedAttributesView.readAttributes() ).thenReturn( generatedFileAttributes );
Metadata metadata = service.create();
assertTrue( metadata.isGenerated() );
}
@Test
//See https://issues.jboss.org/browse/GUVNOR-2399
public void testConcurrency() throws Throwable {
//Ensure FileSystemProviders has been setup
FileSystemProviders.getDefaultProvider();
//Mock FileSystem operations
final AtomicBoolean exists = new AtomicBoolean( false );
when( configIOService.exists( any( Path.class ) ) ).<Boolean>thenAnswer( new Answer<Boolean>() {
@Override
public Boolean answer( InvocationOnMock invocation ) throws Throwable {
return exists.get();
}
} );
when( configIOService.write( any( Path.class ),
any( String.class ) ) ).<Path>thenAnswer( new Answer<Path>() {
@Override
public Path answer( final InvocationOnMock invocation ) throws Throwable {
exists.set( true );
return mainFilePath;
}
} );
when( configIOService.readAllString( any( Path.class ) ) ).<String>thenAnswer( new Answer<String>() {
@Override
public String answer( InvocationOnMock invocation ) throws Throwable {
if ( !exists.get() ) {
throw new NoSuchFileException();
}
return "content";
}
} );
doAnswer( new Answer<Void>() {
@Override
public Void answer( InvocationOnMock invocation ) throws Throwable {
exists.set( false );
return null;
}
} ).when( configIOService ).delete( any( Path.class ) );
final int THREADS = 100;
final Result result = new Result();
final ExecutorService es = Executors.newCachedThreadPool();
for ( int i = 0; i < THREADS; i++ ) {
final int threadCount = i;
final Operation op = i % 2 == 1 ? Operation.WRITE : Operation.CHECK;
es.execute( new Runnable() {
@Override
public void run() {
try {
System.out.println( "[Thread : " + threadCount + "] Running..." );
switch ( op ) {
case WRITE:
System.out.println( "[Thread : " + threadCount + "] Writing..." + output() );
configIOService.write( mainFilePath,
"content" );
configIOService.delete( mainFilePath );
break;
case CHECK:
System.out.println( "[Thread : " + threadCount + "] Checking..." + output() );
service.create();
}
} catch ( Throwable e ) {
result.setFailed( true );
result.setException( e );
} finally {
System.out.println( "[Thread : " + threadCount + "] Completed." );
}
}
private String output() {
if ( exists.get() ) {
return "Exists";
} else {
return "Not exists";
}
}
} );
}
try {
es.shutdown();
es.awaitTermination( 1000 * 5,
TimeUnit.MILLISECONDS );
} catch ( InterruptedException e ) {
}
if ( result.isFailed() ) {
throw result.getException();
}
}
private enum Operation {
WRITE,
CHECK
}
private static class Result {
private Throwable exception;
private boolean failed = false;
public Throwable getException() {
return exception;
}
public void setException( Throwable exception ) {
this.exception = exception;
}
public boolean isFailed() {
return failed;
}
public void setFailed( boolean failed ) {
this.failed = failed;
}
}
private VersionRecord createVersionRecord() {
return new VersionRecord() {
@Override
public String id() {
return "1";
}
@Override
public String author() {
return "admin";
}
@Override
public String email() {
return "admin@mail.zap";
}
@Override
public String comment() {
return "Some commit";
}
@Override
public Date date() {
return new Date();
}
@Override
public String uri() {
return "myfile.file";
}
};
}
}