<commit_before>/*
 * A CCNx library test.
 *
 * Copyright (C) 2008, 2009, 2010, 2011 Palo Alto Research Center, Inc.
 *
 * This work is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 2 as published by the
 * Free Software Foundation. 
 * This work is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details. You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

package org.ccnx.ccn.test.profiles.security.access.group;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.logging.Level;

import junit.framework.Assert;

import org.ccnx.ccn.CCNHandle;
import org.ccnx.ccn.config.SystemConfiguration;
import org.ccnx.ccn.config.UserConfiguration;
import org.ccnx.ccn.impl.CCNFlowControl.SaveType;
import org.ccnx.ccn.impl.support.Log;
import org.ccnx.ccn.io.CCNFileInputStream;
import org.ccnx.ccn.io.CCNInputStream;
import org.ccnx.ccn.io.CCNOutputStream;
import org.ccnx.ccn.io.RepositoryFileOutputStream;
import org.ccnx.ccn.io.content.Link;
import org.ccnx.ccn.profiles.namespace.NamespaceManager;
import org.ccnx.ccn.profiles.namespace.ParameterizedName;
import org.ccnx.ccn.profiles.security.access.AccessControlManager;
import org.ccnx.ccn.profiles.security.access.AccessDeniedException;
import org.ccnx.ccn.profiles.security.access.group.ACL;
import org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager;
import org.ccnx.ccn.profiles.security.access.group.GroupAccessControlProfile;
import org.ccnx.ccn.profiles.security.access.group.ACL.ACLOperation;
import org.ccnx.ccn.protocol.ContentName;
import org.ccnx.ccn.test.CCNTestHelper;
import org.ccnx.ccn.utils.CreateUserData;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class ACPerformanceTestRepo {

	static ContentName domainPrefix, userKeystore, userNamespace, groupNamespace;
	static String[] userNames = {"Alice", "Bob", "Carol"};
	static ContentName baseDirectory, nodeName;
	static CreateUserData cua;
	static final int blockSize = 8096;
	static final int contentSizeInBlocks = 100;
	static Random rnd;
	static CCNHandle _AliceHandle;
	static GroupAccessControlManager _AliceACM;

	int readsize = 1024;
	byte [] buffer = new byte[readsize];
	
	static Level [] logLevels;
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		logLevels = Log.getLevels();
		Log.setDefaultLevel(Log.FAC_ALL, Level.WARNING);
		rnd = new Random();
		
		CCNTestHelper testHelper = new CCNTestHelper(ACPerformanceTestRepo.class);
		domainPrefix = testHelper.getTestNamespace("testInOrder");
		
		userNamespace = GroupAccessControlProfile.userNamespaceName(UserConfiguration.defaultNamespace());
		groupNamespace = GroupAccessControlProfile.groupNamespaceName(UserConfiguration.defaultNamespace());
		userKeystore = ContentName.fromNative(UserConfiguration.defaultNamespace(), "_keystore_"); 
	
		cua = new CreateUserData(userKeystore, userNames, userNames.length, true, "password".toCharArray(), CCNHandle.open());
		cua.publishUserKeysToRepositorySetLocators(userNamespace);

		// The root ACL at domainPrefix has Alice as a manager
		ArrayList<Link> ACLcontents = new ArrayList<Link>();
		Link lk = new Link(ContentName.fromNative(userNamespace, userNames[0]), ACL.LABEL_MANAGER, null);
		ACLcontents.add(lk);
		ACL rootACL = new ACL(ACLcontents);
		
		// Set user and group storage locations as parameterized names
		ArrayList<ParameterizedName> parameterizedNames = new ArrayList<ParameterizedName>();
		ParameterizedName uName = new ParameterizedName("User", userNamespace, null);
		parameterizedNames.add(uName);
		ParameterizedName gName = new ParameterizedName("Group", groupNamespace, null);
		parameterizedNames.add(gName);
		
		// Set access control policy marker, written as default user.
		ContentName profileName = ContentName.fromNative(GroupAccessControlManager.PROFILE_NAME_STRING);
		GroupAccessControlManager.create(domainPrefix, profileName, rootACL, parameterizedNames, null, SaveType.REPOSITORY, CCNHandle.getHandle());
		
		// get handle and ACM for Alice
		_AliceHandle = cua.getHandleForUser(userNames[0]);
		Assert.assertNotNull(_AliceHandle);
		NamespaceManager.clearSearchedPathCache();
		AccessControlManager.loadAccessControlManagerForNamespace(domainPrefix, _AliceHandle);
		
		_AliceACM = (GroupAccessControlManager) AccessControlManager.findACM(domainPrefix, _AliceHandle);
		Assert.assertNotNull(_AliceACM);
		
		// load an ACM for the other users.
		CCNHandle userHandle = null;
		for (int i=1; i < userNames.length; ++i) {
			userHandle = cua.getHandleForUser(userNames[i]);
			AccessControlManager.loadAccessControlManagerForNamespace(domainPrefix, userHandle);
		}
	}
	
	@AfterClass
	public static void tearDownAfterClass() throws Exception {
		cua.closeAll();
		Log.setLevels(logLevels);
	}
	
	@Test
	public void performanceTest() throws AccessDeniedException {
		createBaseDirectoryACL();
		writeContentInDirectory();

		// Alice and Bob have permission to read the file
		readFileAs(userNames[0]);
		readFileAs(userNames[1]);

		// Carol does not have permission to read the file
		try {
			readFileAs(userNames[2]);
			Assert.fail();
		} 
		catch (AccessDeniedException ade) {}

		updateACL();
		
		// Carol now has permission to read the file
		readFileAs(userNames[2]);
	}
	
	/**
	 * Create a new ACL at baseDirectory with Alice as a manager and Bob as a reader
	 */
	public void createBaseDirectoryACL() {
		long startTime = System.currentTimeMillis();

		try {
			baseDirectory = domainPrefix.append(ContentName.fromNative("/Alice/documents/images/"));
			ArrayList<Link> ACLcontents = new ArrayList<Link>();
			ACLcontents.add(new Link(ContentName.fromNative(userNamespace, userNames[0]), ACL.LABEL_MANAGER, null));
			ACLcontents.add(new Link(ContentName.fromNative(userNamespace, userNames[1]), ACL.LABEL_READER, null));		
			ACL baseDirACL = new ACL(ACLcontents);
			_AliceACM.setACL(baseDirectory, baseDirACL);
		}
		catch (Exception e) {
			e.printStackTrace();
			Assert.fail();
		}

		System.out.println("createACL: " + (System.currentTimeMillis() - startTime));
	}
	
	/**
	 * write a file in the baseDirectory
	 */
	public void writeContentInDirectory() {
		long startTime = System.currentTimeMillis();
		
		try {
			nodeName = ContentName.fromNative(baseDirectory, "randomContent");
			CCNOutputStream ostream = new RepositoryFileOutputStream(nodeName, _AliceHandle);
			ostream.setTimeout(SystemConfiguration.MAX_TIMEOUT);
			
			byte [] buffer = new byte[blockSize];
			for (int i=0; i<contentSizeInBlocks; i++) {
				rnd.nextBytes(buffer);
				ostream.write(buffer, 0, blockSize);
			}
			ostream.close();
		} <commit_msg>refs #100465 Allow Exceptions to propagate out of tests so they are logged rather than lost.<commit_after>/*
 * A CCNx library test.
 *
 * Copyright (C) 2008, 2009, 2010, 2011 Palo Alto Research Center, Inc.
 *
 * This work is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 2 as published by the
 * Free Software Foundation. 
 * This work is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details. You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

package org.ccnx.ccn.test.profiles.security.access.group;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.logging.Level;

import junit.framework.Assert;

import org.ccnx.ccn.CCNHandle;
import org.ccnx.ccn.config.SystemConfiguration;
import org.ccnx.ccn.config.UserConfiguration;
import org.ccnx.ccn.impl.CCNFlowControl.SaveType;
import org.ccnx.ccn.impl.support.Log;
import org.ccnx.ccn.io.CCNFileInputStream;
import org.ccnx.ccn.io.CCNInputStream;
import org.ccnx.ccn.io.CCNOutputStream;
import org.ccnx.ccn.io.RepositoryFileOutputStream;
import org.ccnx.ccn.io.content.Link;
import org.ccnx.ccn.profiles.namespace.NamespaceManager;
import org.ccnx.ccn.profiles.namespace.ParameterizedName;
import org.ccnx.ccn.profiles.security.access.AccessControlManager;
import org.ccnx.ccn.profiles.security.access.AccessDeniedException;
import org.ccnx.ccn.profiles.security.access.group.ACL;
import org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager;
import org.ccnx.ccn.profiles.security.access.group.GroupAccessControlProfile;
import org.ccnx.ccn.profiles.security.access.group.ACL.ACLOperation;
import org.ccnx.ccn.protocol.ContentName;
import org.ccnx.ccn.test.CCNTestHelper;
import org.ccnx.ccn.utils.CreateUserData;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class ACPerformanceTestRepo {

	static ContentName domainPrefix, userKeystore, userNamespace, groupNamespace;
	static String[] userNames = {"Alice", "Bob", "Carol"};
	static ContentName baseDirectory, nodeName;
	static CreateUserData cua;
	static final int blockSize = 8096;
	static final int contentSizeInBlocks = 100;
	static Random rnd;
	static CCNHandle _AliceHandle;
	static GroupAccessControlManager _AliceACM;

	int readsize = 1024;
	byte [] buffer = new byte[readsize];
	
	static Level [] logLevels;
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		logLevels = Log.getLevels();
		Log.setDefaultLevel(Log.FAC_ALL, Level.WARNING);
		rnd = new Random();
		
		CCNTestHelper testHelper = new CCNTestHelper(ACPerformanceTestRepo.class);
		domainPrefix = testHelper.getTestNamespace("testInOrder");
		
		userNamespace = GroupAccessControlProfile.userNamespaceName(UserConfiguration.defaultNamespace());
		groupNamespace = GroupAccessControlProfile.groupNamespaceName(UserConfiguration.defaultNamespace());
		userKeystore = ContentName.fromNative(UserConfiguration.defaultNamespace(), "_keystore_"); 
	
		cua = new CreateUserData(userKeystore, userNames, userNames.length, true, "password".toCharArray(), CCNHandle.open());
		cua.publishUserKeysToRepositorySetLocators(userNamespace);

		// The root ACL at domainPrefix has Alice as a manager
		ArrayList<Link> ACLcontents = new ArrayList<Link>();
		Link lk = new Link(ContentName.fromNative(userNamespace, userNames[0]), ACL.LABEL_MANAGER, null);
		ACLcontents.add(lk);
		ACL rootACL = new ACL(ACLcontents);
		
		// Set user and group storage locations as parameterized names
		ArrayList<ParameterizedName> parameterizedNames = new ArrayList<ParameterizedName>();
		ParameterizedName uName = new ParameterizedName("User", userNamespace, null);
		parameterizedNames.add(uName);
		ParameterizedName gName = new ParameterizedName("Group", groupNamespace, null);
		parameterizedNames.add(gName);
		
		// Set access control policy marker, written as default user.
		ContentName profileName = ContentName.fromNative(GroupAccessControlManager.PROFILE_NAME_STRING);
		GroupAccessControlManager.create(domainPrefix, profileName, rootACL, parameterizedNames, null, SaveType.REPOSITORY, CCNHandle.getHandle());
		
		// get handle and ACM for Alice
		_AliceHandle = cua.getHandleForUser(userNames[0]);
		Assert.assertNotNull(_AliceHandle);
		NamespaceManager.clearSearchedPathCache();
		AccessControlManager.loadAccessControlManagerForNamespace(domainPrefix, _AliceHandle);
		
		_AliceACM = (GroupAccessControlManager) AccessControlManager.findACM(domainPrefix, _AliceHandle);
		Assert.assertNotNull(_AliceACM);
		
		// load an ACM for the other users.
		CCNHandle userHandle = null;
		for (int i=1; i < userNames.length; ++i) {
			userHandle = cua.getHandleForUser(userNames[i]);
			AccessControlManager.loadAccessControlManagerForNamespace(domainPrefix, userHandle);
		}
	}
	
	@AfterClass
	public static void tearDownAfterClass() throws Exception {
		cua.closeAll();
		Log.setLevels(logLevels);
	}
	
	@Test
	public void performanceTest() throws Exception {
		createBaseDirectoryACL();
		writeContentInDirectory();

		// Alice and Bob have permission to read the file
		readFileAs(userNames[0]);
		readFileAs(userNames[1]);

		// Carol does not have permission to read the file
		try {
			readFileAs(userNames[2]);
			Assert.fail();
		} 
		catch (AccessDeniedException ade) {}

		updateACL();
		
		// Carol now has permission to read the file
		readFileAs(userNames[2]);
	}
	
	/**
	 * Create a new ACL at baseDirectory with Alice as a manager and Bob as a reader
	 */
	public void createBaseDirectoryACL() throws Exception {
		long startTime = System.currentTimeMillis();

		baseDirectory = domainPrefix.append(ContentName.fromNative("/Alice/documents/images/"));
		ArrayList<Link> ACLcontents = new ArrayList<Link>();
		ACLcontents.add(new Link(ContentName.fromNative(userNamespace, userNames[0]), ACL.LABEL_MANAGER, null));
		ACLcontents.add(new Link(ContentName.fromNative(userNamespace, userNames[1]), ACL.LABEL_READER, null));		
		ACL baseDirACL = new ACL(ACLcontents);
		_AliceACM.setACL(baseDirectory, baseDirACL);

		System.out.println("createACL: " + (System.currentTimeMillis() - startTime));
	}
	
	/**
	 * write a file in the baseDirectory
	 */
	public void writeContentInDirectory() {
		long startTime = System.currentTimeMillis();
		
		try {
			nodeName = ContentName.fromNative(baseDirectory, "randomContent");
			CCNOutputStream ostream = new RepositoryFileOutputStream(nodeName, _AliceHandle);
			ostream.setTimeout(SystemConfiguration.MAX_TIMEOUT);
			
			byte [] buffer = new byte[blockSize];
			for (int i=0; i<contentSizeInBlocks; i++) {
				rnd.nextBytes(buffer);
				ostream.write(buffer, 0, blockSize);
			}
			ostream.close();
		} 
{'fraction_non_alphanumeric': 0.09994329458463283, 'fraction_numerical': 0.007513467536149702, 'mean_word_length': 5.295850066934404, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 15, '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': '3755343', 'n_tokens_mistral': 4597, 'n_tokens_neox': 4176, 'n_words': 1043}