<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2011-2016 Incapture Technologies LLC
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package rapture.lock;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.testng.Assert;
import org.testng.Reporter;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import rapture.common.LockHandle;
import rapture.common.RaptureLockConfig;
import rapture.common.RaptureURI;
import rapture.common.Scheme;
import rapture.common.client.HttpAdminApi;
import rapture.common.client.HttpLockApi;
import rapture.common.impl.jackson.MD5Utils;
import rapture.helper.IntegrationTestHelper;

public class LockApiTest {
    
    private IntegrationTestHelper helper;
    private HttpLockApi lockApi = null;
    private HttpAdminApi admin = null;

    private static final String user = "User";
    private IntegrationTestHelper helper2;
    private HttpLockApi lockApi2 = null;
    private RaptureURI repoUri = null;

    @BeforeClass(groups =  { "nightly", "lock" })
    @Parameters({ "RaptureURL", "RaptureUser", "RapturePassword" })
    public void setUp(@Optional("http://localhost:8665/rapture") String url, @Optional("rapture") String username, @Optional("rapture") String password) {
        helper = new IntegrationTestHelper(url, username, password);
        lockApi = helper.getLockApi();
        admin = helper.getAdminApi();
        if (!admin.doesUserExist(user)) {
            admin.addUser(user, "Another User", MD5Utils.hash16(user), "<EMAIL>");
        }

        helper2 = new IntegrationTestHelper(url, user, user);
        lockApi2 = helper2.getLockApi();

        repoUri = helper.getRandomAuthority(Scheme.DOCUMENT);
        helper.configureTestRepo(repoUri, "MONGODB"); // TODO Make this configurable
    }

	@AfterClass(groups = { "nightly", "lock" })
	public void tearDown() {
		helper.cleanAllAssets();
		helper2.cleanAllAssets();
	}

	String winningContent;
	String winningPath;
	LockHandle lockHandle;
	List<String> winningContentList;

	@Test(groups = { "nightly", "lock" })
	public void testMultipleRequestsAcquireReleaseLockZookeeper() {
		int threadCount = 25;
		winningContentList = new ArrayList<String>();
		winningContent = "";
		winningPath = "";
		lockHandle = null;
		RaptureURI lockUri = RaptureURI.builder(helper.getRandomAuthority(Scheme.DOCUMENT)).docPath("foo/bar" + System.currentTimeMillis()).build();
		RaptureLockConfig lockConfig = lockApi.createLockManager(lockUri.toString(), "LOCKING USING ZOOKEEPER {}", "");
		Random rand = new Random();

		RaptureURI docRepoUri = helper.getRandomAuthority(Scheme.DOCUMENT);
		helper.configureTestRepo(docRepoUri, "MONGODB", true);
		List<Long> threadList = new ArrayList<Long>();

		class LockThread implements Runnable {
			public void run() {
				long currThreadId = Thread.currentThread().getId();
				threadList.add(new Long(currThreadId));
				try {
					Double timeDelay = rand.nextDouble() * 5000;
					String content = "{\"key_" + currThreadId + "_" + rand.nextInt(5000) + "\" : \"" + currThreadId + "\" }";
					Reporter.log("Thread id " + currThreadId + " waiting for " + timeDelay.longValue() + " ms.", true);
					Thread.sleep(timeDelay.longValue());

					lockHandle = lockApi.acquireLock(lockUri.toString(), lockConfig.getName(), 2, 10);
					if (lockHandle != null) {
						winningPath = docRepoUri + "doc" + currThreadId;
						helper.getDocApi().putDoc(winningPath, content);
						winningContentList.add(content);
						Reporter.log("Thread id " + currThreadId + " acquired lock and wrote doc: " + content + " to " + winningPath, true);

						Thread.sleep(1000);
						Assert.assertTrue(lockApi.releaseLock(lockUri.toString(), lockConfig.getName(), lockHandle));
					} else {
						Reporter.log("Thread id " + currThreadId + " did not acquire lock.", true);
					}

				} catch (Exception e) {
					Reporter.log("Exception with thread " + currThreadId + ", " + e.getMessage(), true);
				}
				threadList.remove(new Long(currThreadId));
			}
		}

		Reporter.log("Running test with " + threadCount + " threads", true);
		for (int i = 0; i < threadCount; i++)
			new Thread(new LockThread()).start();

		while (threadList.size() > 0) {
			try {
				Thread.sleep(500);
				if (helper.getDocApi().getDoc(winningPath) != null) {
					Assert.assertTrue(winningContentList.contains(helper.getDocApi().getDoc(winningPath)));
				}
			} catch (Exception e) {
			}
		}

	}

	@Test(groups = { "nightly", "lock" }, dataProvider = "threadScenarios")
	public void testOneThreadBlockingMultipleRequestsZookeeper(Integer threadCount) {
		winningContent = "";
		winningPath = "";
		lockHandle = null;
		RaptureURI lockUri = RaptureURI.builder(helper.getRandomAuthority(Scheme.DOCUMENT)).docPath("foo/bar" + System.currentTimeMillis()).build();
		RaptureLockConfig lockConfig = lockApi.createLockManager(lockUri.toString(), "LOCKING USING ZOOKEEPER {}", "");
		Random rand = new Random();

		RaptureURI docRepoUri = helper.getRandomAuthority(Scheme.DOCUMENT);
		helper.configureTestRepo(docRepoUri, "MONGODB", true);
		List<Long> threadList = new ArrayList<Long>();

		class LockThread implements Runnable {
			public void run() {
				long currThreadId = Thread.currentThread().getId();
				threadList.add(new Long(currThreadId));<commit_msg>UNFILED: change document repo to not use versioning<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2011-2016 Incapture Technologies LLC
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package rapture.lock;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.testng.Assert;
import org.testng.Reporter;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import rapture.common.LockHandle;
import rapture.common.RaptureLockConfig;
import rapture.common.RaptureURI;
import rapture.common.Scheme;
import rapture.common.client.HttpAdminApi;
import rapture.common.client.HttpLockApi;
import rapture.common.impl.jackson.MD5Utils;
import rapture.helper.IntegrationTestHelper;

public class LockApiTest {
    
    private IntegrationTestHelper helper;
    private HttpLockApi lockApi = null;
    private HttpAdminApi admin = null;

    private static final String user = "User";
    private IntegrationTestHelper helper2;
    private HttpLockApi lockApi2 = null;
    private RaptureURI repoUri = null;

    @BeforeClass(groups =  { "nightly", "lock" })
    @Parameters({ "RaptureURL", "RaptureUser", "RapturePassword" })
    public void setUp(@Optional("http://localhost:8665/rapture") String url, @Optional("rapture") String username, @Optional("rapture") String password) {
        helper = new IntegrationTestHelper(url, username, password);
        lockApi = helper.getLockApi();
        admin = helper.getAdminApi();
        if (!admin.doesUserExist(user)) {
            admin.addUser(user, "Another User", MD5Utils.hash16(user), "<EMAIL>");
        }

        helper2 = new IntegrationTestHelper(url, user, user);
        lockApi2 = helper2.getLockApi();

        repoUri = helper.getRandomAuthority(Scheme.DOCUMENT);
        helper.configureTestRepo(repoUri, "MONGODB"); // TODO Make this configurable
    }

	@AfterClass(groups = { "nightly", "lock" })
	public void tearDown() {
		helper.cleanAllAssets();
		helper2.cleanAllAssets();
	}

	String winningContent;
	String winningPath;
	LockHandle lockHandle;
	List<String> winningContentList;

	@Test(groups = { "nightly", "lock" })
	public void testMultipleRequestsAcquireReleaseLockZookeeper() {
		int threadCount = 25;
		winningContentList = new ArrayList<String>();
		winningContent = "";
		winningPath = "";
		lockHandle = null;
		RaptureURI lockUri = RaptureURI.builder(helper.getRandomAuthority(Scheme.DOCUMENT)).docPath("foo/bar" + System.currentTimeMillis()).build();
		RaptureLockConfig lockConfig = lockApi.createLockManager(lockUri.toString(), "LOCKING USING ZOOKEEPER {}", "");
		Random rand = new Random();

		RaptureURI docRepoUri = helper.getRandomAuthority(Scheme.DOCUMENT);
		helper.configureTestRepo(docRepoUri, "MONGODB", true);
		List<Long> threadList = new ArrayList<Long>();

		class LockThread implements Runnable {
			public void run() {
				long currThreadId = Thread.currentThread().getId();
				threadList.add(new Long(currThreadId));
				try {
					Double timeDelay = rand.nextDouble() * 5000;
					String content = "{\"key_" + currThreadId + "_" + rand.nextInt(5000) + "\" : \"" + currThreadId + "\" }";
					Reporter.log("Thread id " + currThreadId + " waiting for " + timeDelay.longValue() + " ms.", true);
					Thread.sleep(timeDelay.longValue());

					lockHandle = lockApi.acquireLock(lockUri.toString(), lockConfig.getName(), 2, 10);
					if (lockHandle != null) {
						winningPath = docRepoUri + "doc" + currThreadId;
						helper.getDocApi().putDoc(winningPath, content);
						winningContentList.add(content);
						Reporter.log("Thread id " + currThreadId + " acquired lock and wrote doc: " + content + " to " + winningPath, true);

						Thread.sleep(1000);
						Assert.assertTrue(lockApi.releaseLock(lockUri.toString(), lockConfig.getName(), lockHandle));
					} else {
						Reporter.log("Thread id " + currThreadId + " did not acquire lock.", true);
					}

				} catch (Exception e) {
					Reporter.log("Exception with thread " + currThreadId + ", " + e.getMessage(), true);
				}
				threadList.remove(new Long(currThreadId));
			}
		}

		Reporter.log("Running test with " + threadCount + " threads", true);
		for (int i = 0; i < threadCount; i++)
			new Thread(new LockThread()).start();

		while (threadList.size() > 0) {
			try {
				Thread.sleep(500);
				if (helper.getDocApi().getDoc(winningPath) != null) {
					Assert.assertTrue(winningContentList.contains(helper.getDocApi().getDoc(winningPath)));
				}
			} catch (Exception e) {
			}
		}

	}

	@Test(groups = { "nightly", "lock" }, dataProvider = "threadScenarios")
	public void testOneThreadBlockingMultipleRequestsZookeeper(Integer threadCount) {
		winningContent = "";
		winningPath = "";
		lockHandle = null;
		RaptureURI lockUri = RaptureURI.builder(helper.getRandomAuthority(Scheme.DOCUMENT)).docPath("foo/bar" + System.currentTimeMillis()).build();
		RaptureLockConfig lockConfig = lockApi.createLockManager(lockUri.toString(), "LOCKING USING ZOOKEEPER {}", "");
		Random rand = new Random();

		RaptureURI docRepoUri = helper.getRandomAuthority(Scheme.DOCUMENT);
		helper.configureTestRepo(docRepoUri, "MONGODB", false);
		List<Long> threadList = new ArrayList<Long>();

		class LockThread implements Runnable {
			public void run() {
				long currThreadId = Thread.currentThread().getId();
				threadList.add(new Long(currThreadId));
{'fraction_non_alphanumeric': 0.11668017984816098, 'fraction_numerical': 0.006486327117269846, 'mean_word_length': 4.409888357256778, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5999719', 'n_tokens_mistral': 4308, 'n_tokens_neox': 3933, 'n_words': 1054}