001package org.eclipse.aether.internal.impl;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 * 
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 * 
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import static org.junit.Assert.*;
023
024import java.io.File;
025import java.util.ArrayList;
026import java.util.Collections;
027import java.util.HashMap;
028import java.util.List;
029import java.util.Map;
030import java.util.Properties;
031
032import org.eclipse.aether.internal.impl.TrackingFileManager;
033import org.eclipse.aether.internal.test.util.TestFileUtils;
034import org.junit.Test;
035
036/**
037 */
038public class TrackingFileManagerTest
039{
040
041    @Test
042    public void testRead()
043        throws Exception
044    {
045        TrackingFileManager tfm = new TrackingFileManager();
046
047        File propFile = TestFileUtils.createTempFile( "#COMMENT\nkey1=value1\nkey2 : value2" );
048        Properties props = tfm.read( propFile );
049
050        assertNotNull( props );
051        assertEquals( String.valueOf( props ), 2, props.size() );
052        assertEquals( "value1", props.get( "key1" ) );
053        assertEquals( "value2", props.get( "key2" ) );
054
055        assertTrue( "Leaked file: " + propFile, propFile.delete() );
056
057        props = tfm.read( propFile );
058        assertNull( String.valueOf( props ), props );
059    }
060
061    @Test
062    public void testReadNoFileLeak()
063        throws Exception
064    {
065        TrackingFileManager tfm = new TrackingFileManager();
066
067        for ( int i = 0; i < 1000; i++ )
068        {
069            File propFile = TestFileUtils.createTempFile( "#COMMENT\nkey1=value1\nkey2 : value2" );
070            assertNotNull( tfm.read( propFile ) );
071            assertTrue( "Leaked file: " + propFile, propFile.delete() );
072        }
073    }
074
075    @Test
076    public void testUpdate()
077        throws Exception
078    {
079        TrackingFileManager tfm = new TrackingFileManager();
080
081        // NOTE: The excessive repetitions are to check the update properly truncates the file
082        File propFile = TestFileUtils.createTempFile( "key1=value1\nkey2 : value2\n".getBytes( "UTF-8" ), 1000 );
083
084        Map<String, String> updates = new HashMap<String, String>();
085        updates.put( "key1", "v" );
086        updates.put( "key2", null );
087
088        tfm.update( propFile, updates );
089
090        Properties props = tfm.read( propFile );
091
092        assertNotNull( props );
093        assertEquals( String.valueOf( props ), 1, props.size() );
094        assertEquals( "v", props.get( "key1" ) );
095        assertNull( String.valueOf( props.get( "key2" ) ), props.get( "key2" ) );
096    }
097
098    @Test
099    public void testUpdateNoFileLeak()
100        throws Exception
101    {
102        TrackingFileManager tfm = new TrackingFileManager();
103
104        Map<String, String> updates = new HashMap<String, String>();
105        updates.put( "k", "v" );
106
107        for ( int i = 0; i < 1000; i++ )
108        {
109            File propFile = TestFileUtils.createTempFile( "#COMMENT\nkey1=value1\nkey2 : value2" );
110            assertNotNull( tfm.update( propFile, updates ) );
111            assertTrue( "Leaked file: " + propFile, propFile.delete() );
112        }
113    }
114
115    @Test
116    public void testLockingOnCanonicalPath()
117        throws Exception
118    {
119        final TrackingFileManager tfm = new TrackingFileManager();
120
121        final File propFile = TestFileUtils.createTempFile( "#COMMENT\nkey1=value1\nkey2 : value2" );
122
123        final List<Throwable> errors = Collections.synchronizedList( new ArrayList<Throwable>() );
124
125        Thread[] threads = new Thread[4];
126        for ( int i = 0; i < threads.length; i++ )
127        {
128            String path = propFile.getParent();
129            for ( int j = 0; j < i; j++ )
130            {
131                path += "/.";
132            }
133            path += "/" + propFile.getName();
134            final File file = new File( path );
135
136            threads[i] = new Thread()
137            {
138                public void run()
139                {
140                    try
141                    {
142                        for ( int i = 0; i < 1000; i++ )
143                        {
144                            assertNotNull( tfm.read( file ) );
145                        }
146                    }
147                    catch ( Throwable e )
148                    {
149                        errors.add( e );
150                    }
151                }
152            };
153        }
154
155        for ( Thread thread1 : threads )
156        {
157            thread1.start();
158        }
159
160        for ( Thread thread : threads )
161        {
162            thread.join();
163        }
164
165        assertEquals( Collections.emptyList(), errors );
166    }
167
168}