/*******************************************************************************
* Copyright (c) 2010, 2011 Sonatype, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sonatype, Inc. - initial API and implementation
*******************************************************************************/
package io.takari.aether.localrepo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.eclipse.aether.internal.test.util.TestFileUtils;
import org.junit.Test;
public class TrackingFileManagerTest {
@Test
public void testRead() throws Exception {
TrackingFileManager tfm = new TrackingFileManager();
File propFile = TestFileUtils.createTempFile("#COMMENT\nkey1=value1\nkey2 : value2");
Properties props = tfm.read(propFile);
assertNotNull(props);
assertEquals(String.valueOf(props), 2, props.size());
assertEquals("value1", props.get("key1"));
assertEquals("value2", props.get("key2"));
assertTrue("Leaked file: " + propFile, propFile.delete());
props = tfm.read(propFile);
assertNull(String.valueOf(props), props);
}
@Test
public void testReadNoFileLeak() throws Exception {
TrackingFileManager tfm = new TrackingFileManager();
for (int i = 0; i < 1000; i++) {
File propFile = TestFileUtils.createTempFile("#COMMENT\nkey1=value1\nkey2 : value2");
assertNotNull(tfm.read(propFile));
assertTrue("Leaked file: " + propFile, propFile.delete());
}
}
@Test
public void testUpdate() throws Exception {
TrackingFileManager tfm = new TrackingFileManager();
// NOTE: The excessive repetitions are to check the update properly truncates the file
File propFile = TestFileUtils.createTempFile("key1=value1\nkey2 : value2\n".getBytes("UTF-8"), 1000);
Map<String, String> updates = new HashMap<String, String>();
updates.put("key1", "v");
updates.put("key2", null);
tfm.update(propFile, updates);
Properties props = tfm.read(propFile);
assertNotNull(props);
assertEquals(String.valueOf(props), 1, props.size());
assertEquals("v", props.get("key1"));
assertNull(String.valueOf(props.get("key2")), props.get("key2"));
}
@Test
public void testUpdateNoFileLeak() throws Exception {
TrackingFileManager tfm = new TrackingFileManager();
Map<String, String> updates = new HashMap<String, String>();
updates.put("k", "v");
for (int i = 0; i < 1000; i++) {
File propFile = TestFileUtils.createTempFile("#COMMENT\nkey1=value1\nkey2 : value2");
assertNotNull(tfm.update(propFile, updates));
assertTrue("Leaked file: " + propFile, propFile.delete());
}
}
@Test
public void testLockingOnCanonicalPath() throws Exception {
final TrackingFileManager tfm = new TrackingFileManager();
final File propFile = TestFileUtils.createTempFile("#COMMENT\nkey1=value1\nkey2 : value2");
final List<Throwable> errors = Collections.synchronizedList(new ArrayList<Throwable>());
Thread[] threads = new Thread[4];
for (int i = 0; i < threads.length; i++) {
String path = propFile.getParent();
for (int j = 0; j < i; j++) {
path += "/.";
}
path += "/" + propFile.getName();
final File file = new File(path);
threads[i] = new Thread() {
public void run() {
try {
for (int i = 0; i < 1000; i++) {
assertNotNull(tfm.read(file));
}
} catch (Throwable e) {
errors.add(e);
}
}
};
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
for (int i = 0; i < threads.length; i++) {
threads[i].join();
}
assertEquals(Collections.emptyList(), errors);
}
}