Index: tests/scaling_tests/daisychain/Makefile
===================================================================
--- tests/scaling_tests/daisychain/Makefile	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
+++ tests/scaling_tests/daisychain/Makefile	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
@@ -0,0 +1,22 @@
+
+
+DIRECTORY=likes_python
+
+.PHONY : runcheck clean
+runcheck: $(DIRECTORY)
+
+clean:
+	@for i in $(DIRECTORY); do \
+	export here=`pwd`; \
+	cd $$i; \
+	make clean; \
+	cd $$here;\
+	done;
+
+runcheck: 
+	@for i in $(DIRECTORY); do \
+	export here=`pwd`; \
+	cd $$i; \
+	make -s test; \
+	cd $$here;\
+	done;
Index: tests/scaling_tests/daisychain/likes_python/Makefile
===================================================================
--- tests/scaling_tests/daisychain/likes_python/Makefile	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
+++ tests/scaling_tests/daisychain/likes_python/Makefile	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
@@ -0,0 +1,31 @@
+
+
+TEST=likes_0 likes_10 likes_20
+TIMING=likes_30 likes_40 likes_50 likes_100 likes_150 likes_200
+#TIMING=likes_200
+
+.PHONY : test timing plot 
+
+test: $(TEST)
+
+timing: $(TIMING)
+
+likes_0 :
+	@./run_one 0
+likes_10 :
+	@./run_one 10
+likes_20 :
+	@./run_one 20
+
+clean: 
+	@rm -rf likes_* run_plot plot timing
+
+$(TIMING):
+	@./run_one $(subst likes_,,$@)
+
+plot:
+	@make clean
+	cp ../../plotting/run_plot .
+	@make -s test
+	@make -s timing
+	@./run_plot likes
Index: tests/scaling_tests/daisychain/likes_python/base/ATTR.py
===================================================================
--- tests/scaling_tests/daisychain/likes_python/base/ATTR.py	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
+++ tests/scaling_tests/daisychain/likes_python/base/ATTR.py	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+
+"""
+See README in this directory for the semantics of the example.  This file
+constructs the credentials described and puts copies into this directory
+
+cmd1:env keystore=`pwd` ./attr.py 
+"""
+
+import os
+import ABAC
+
+ctxt = ABAC.Context()
+
+# Keystore is the directory containing the principal credentials.
+# Load existing principals and/or policy credentials
+if (os.environ.has_key("keystore")) :
+    keystore=os.environ["keystore"]
+    ctxt.load_directory(keystore)
+else:
+    print("keystore is not set...")
+    exit(1)
+
+################################################
+# [keyid:john0].role:likes  <- [keyid:john0]
+a="John0_ID.pem"
+ap="John0_private.pem"
+f="John0_likes__John0_attr.xml" 
+   
+aID=ABAC.ID(a);
+aID.load_privkey(ap);
+aid=aID.keyid()
+
+attr = ABAC.Attribute(aID, "likes", 0)
+attr.principal(aid)
+attr.bake()
+attr.write_file(f)
+
+# [keyid:john1].role:likes  <- [keyid:john0].role:likes
+i=1
+while i <= #VAL#:
+    n=i-1
+
+    a="John%s_ID.pem"%i
+    ap="John%s_private.pem"%i
+    b="John%s_ID.pem"%n
+    f="John%s_likes__John%s_likes_attr.xml" %(i,n)
+   
+    aID=ABAC.ID(a);
+    aID.load_privkey(ap);
+    aid=aID.keyid()
+    bID=ABAC.ID(b);
+    bid=bID.keyid()
+
+    attr = ABAC.Attribute(aID,"likes", 0)
+    attr.role(bid,"likes")
+    attr.bake()
+    attr.write_file(f)
+    i=i+1
+
Index: tests/scaling_tests/daisychain/likes_python/base/PROVE.sh
===================================================================
--- tests/scaling_tests/daisychain/likes_python/base/PROVE.sh	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
+++ tests/scaling_tests/daisychain/likes_python/base/PROVE.sh	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+keystore=`pwd`
+pID=`creddy --keyid --cert ${keystore}/John#VAL#_ID.pem`
+cID=`creddy --keyid --cert ${keystore}/John0_ID.pem`
+
+#JohnX likes John0?
+
+role="${pID}.likes"
+principal="${cID}"
+
+$keystore/../../../../example_scripts/c/abac_prover "$keystore" "$role" "$principal"
+
+#echo "$keystore" "$role" "$principal"
+#gdb $keystore/../../../../example_scripts/c/abac_prover
+
+
Index: tests/scaling_tests/daisychain/likes_python/base/QUERY.py
===================================================================
--- tests/scaling_tests/daisychain/likes_python/base/QUERY.py	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
+++ tests/scaling_tests/daisychain/likes_python/base/QUERY.py	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
@@ -0,0 +1,185 @@
+#!/usr/bin/env python
+
+"""
+Run the queries described in README
+
+cmd: env keystore=`pwd` ./query.py
+
+"""
+
+import os
+import sys
+import ABAC
+import time
+import datetime
+import math
+
+debug=0
+
+ctxt = ABAC.Context()
+
+cred_count = 2 + 2 * #VAL#
+
+def get_msec(e_time) :
+    msec_delta=0
+    if( int(e_time.seconds) !=0 ) :
+        msec_delta= int(e_time.seconds) *1000
+    if( int(e_time.microseconds) !=0) :
+        msec_delta = msec_delta + int(e_time.microseconds)/1000
+    return msec_delta
+
+def get_micro(e_time) :
+    micro_delta=0
+    if( int(e_time.seconds) !=0 ) :
+        micro_delta= int(e_time.seconds) *1000000
+    if( int(e_time.microseconds) !=0) :
+        micro_delta = micro_delta + int(e_time.microseconds)
+    return micro_delta
+
+def extract_delta(starttime, endtime) :
+    """ given a start time, and a endtime, extract delta """
+    elapsed_time = (endtime - starttime)
+# Only handle in seconds/microseconds
+    if ( int(elapsed_time.days) != 0 ) :
+        sys.stderr,write("%s is longer than a day !!!" % msg)
+        exit(1)
+    return elapsed_time
+
+
+# Keystore is the directory containing the principal credentials.
+# Load existing principals and/or policy credentials
+if (os.environ.has_key("keystore")) :
+    keystore=os.environ["keystore"]
+    starttime = datetime.datetime.now()
+    ctxt.load_directory(keystore)
+    endtime = datetime.datetime.now()
+    elapsed_load=extract_delta(starttime, endtime)
+    elapsed_msec=get_msec(elapsed_load)
+    sys.stderr.write("%d %d LOAD(msec)\n" % (cred_count,elapsed_msec))
+else:
+    print("keystore is not set...")
+    exit(1)
+
+##########################################################################
+# dump the loaded principals/policies
+#
+
+fd=os.open("creds_dump",os.O_WRONLY|os.O_CREAT)
+credentials = ctxt.credentials()
+for cred in credentials:
+    string="%s <- %s" % (cred.head().string(), cred.tail().string())
+    os.write(fd,string) 
+    os.write(fd,"\n")
+os.close(fd)
+
+##########################################################################
+# Does JohnX likes John0 ?
+# role = [keyid:JohnX].role:after 
+# p [Keyid:john0]
+def goodQuery() :
+    aid="John%s_ID.pem"% #VAL#
+    aID=ABAC.ID(aid)
+    bID=ABAC.ID("John0_ID.pem")
+
+    print "\n===good============ johnN.likes <- john0 "
+    starttime = datetime.datetime.now()
+    (success, credentials) = ctxt.query("%s.likes" % aID.keyid(), bID.keyid())
+    if success:
+        print "success"
+    else:
+        print "failure"
+    endtime = datetime.datetime.now()
+    if(debug):
+        print "good query start-> %s\n" % starttime
+        print "good query end  -> %s\n" % endtime
+    for cred in credentials:
+        print "%s <- %s" % (cred.head().string(), cred.tail().string())
+    return extract_delta(starttime, endtime)
+    
+
+##########################################################################
+# Does John0 likes JohnX ?
+# role = [keyid:JohnX].role:after 
+# p [Keyid:john0]
+def badQuery() :
+    bid="John%s_ID.pem"% #VAL#
+    bID=ABAC.ID(bid)
+    aID=ABAC.ID("John0_ID.pem")
+
+    print "\n===bad============ john0.likes <- johnX "
+    starttime = datetime.datetime.now()
+    (success, credentials) = ctxt.query("%s.likes" % aID.keyid(), bID.keyid())
+    if success:
+        print "success"
+    else:
+        print "failure"
+    endtime = datetime.datetime.now()
+    for cred in credentials:
+        print "%s <- %s" % (cred.head().string(), cred.tail().string())
+    return extract_delta(starttime, endtime)
+        
+##############################################################
+
+#skip the first one
+e_time=goodQuery()
+elapsed_micro=get_micro(e_time)
+sys.stderr.write("%d %d GOOD_f(micro)\n" % (cred_count,elapsed_micro))
+
+tlist=[]
+k=100
+while(k):
+    e_time=goodQuery()
+    elapsed_micro=get_micro(e_time)
+    k=k-1
+    tlist.append(elapsed_micro)
+    if(k==99):
+       sys.stderr.write("%d %d GOOD_s(micro)\n" % (cred_count,elapsed_micro))
+
+    if(debug):
+        sys.stderr.write("%d %d GOOD_%d(micro)\n" % (cred_count,elapsed_micro,k))
+
+sum=0
+for i in tlist:
+    sum=sum+i
+ave=sum/100
+dlist = [(x-ave) for x in tlist ]
+slist = [ (x-ave)*(x-ave) for x in tlist]
+sum=0
+for i in slist:
+    sum=sum+i
+sd=math.sqrt(sum/99)
+sys.stderr.write("%d %d %d GOOD_t(micro)\n" % (cred_count,ave,sd))
+sys.stderr.write("%d 100 %s GOOD_list(micro)\n" % (cred_count,tlist))
+
+
+###############################################################
+
+e_time=badQuery()
+elapsed_micro=get_micro(e_time)
+sys.stderr.write("%d %d BAD_f(micro)\n" % (cred_count,elapsed_micro))
+
+tlist=[]
+k=100
+while(k):
+    e_time=badQuery()
+    elapsed_micro=get_micro(e_time)
+    tlist.append(elapsed_micro)
+    k=k-1
+    if(k==99):
+        sys.stderr.write("%d %d BAD_s(micro)\n" % (cred_count,elapsed_micro))
+
+    if(debug):
+        sys.stderr.write("%d %d BAD_%d(micro)\n" % (cred_count,elapsed_micro,k))
+
+sum=0
+for i in tlist:
+    sum=sum+i
+ave=sum/100
+dlist = [(x-ave) for x in tlist ]
+slist = [ (x-ave)*(x-ave) for x in tlist]
+sum=0
+for i in slist:
+    sum=sum+i
+sd=math.sqrt(sum/99)
+sys.stderr.write("%d %d %d BAD_t(micro)\n" % (cred_count,ave, sd))
+sys.stderr.write("%d 100 %s BAD_list(micro)\n" % (cred_count,tlist))
Index: tests/scaling_tests/daisychain/likes_python/base/README
===================================================================
--- tests/scaling_tests/daisychain/likes_python/base/README	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
+++ tests/scaling_tests/daisychain/likes_python/base/README	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
@@ -0,0 +1,27 @@
+#!/bin/sh
+#
+#  This demonstrates scalability of libabac.
+#  A basic chaining attribute rule, Ai+1.likes <- Ai.likes 
+#  and the borderline case of Ao.likes <- Ao are created in
+#  ATTR.py. X of these attribute rules are made, where the 
+#  matching ID principals are made in SETUP.py.
+#  A query of Ax.likes <-?- Ao will let us know how fast
+#  do the prolog db runs down the X attribute rules to arrive
+#  at the solution and also Ao.likes <-?- Ax tells us
+#  how long it takes to not validate the assumption
+
+# borderline Credential
+# [keyid:John0].role:likes <- [keyid:John0]
+#
+# [keyid:John1].role:likes <- [keyid:John0].likes
+# John1 likes everything John0 likes
+#
+# [keyid:John2].role:likes <- [keyid:John1].likes
+#
+# and so on
+
+# good query,   Does JohnN likes John0 ?
+#   [keyid:JohnN].role:likes <-?- [keyid:John0]
+#
+# bad query,    Does John0 likes JohnN?
+#   [keyid:John0].role:likes <-?- [keyid:JohnN]
Index: tests/scaling_tests/daisychain/likes_python/base/SETUP.py
===================================================================
--- tests/scaling_tests/daisychain/likes_python/base/SETUP.py	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
+++ tests/scaling_tests/daisychain/likes_python/base/SETUP.py	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+
+"""
+See README for the semantics.  This creates principals
+used by the example.
+"""
+import os
+import ABAC
+
+ctxt = ABAC.Context()
+
+i=0
+while i <= #VAL#:
+     n="John%s"%i 
+     nid="%s_ID.pem"%n
+     np="%s_private.pem"%n
+     aD=ABAC.ID(n, 0)
+     aD.write_cert_file(nid)
+     aD.write_privkey_file(np)
+     i = i+1
+
+
+
Index: tests/scaling_tests/daisychain/likes_python/run_one
===================================================================
--- tests/scaling_tests/daisychain/likes_python/run_one	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
+++ tests/scaling_tests/daisychain/likes_python/run_one	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
@@ -0,0 +1,51 @@
+#!/bin/sh 
+
+noise=$1
+
+if [ -z "$noise" ]; then
+    exit
+fi 
+
+echo "---running daisychain likes_python $noise scaling"
+
+rm -rf likes_$noise
+mkdir likes_$noise
+sed "s/#VAL#/$noise/" base/SETUP.py > likes_$noise/setup.py
+sed "s/#VAL#/$noise/" base/QUERY.py > likes_$noise/query.py
+sed "s/#VAL#/$noise/" base/ATTR.py > likes_$noise/attr.py
+sed "s/#VAL#/$noise/" base/PROVE.sh > likes_$noise/prove.sh
+
+cd likes_$noise
+chmod +x setup.py attr.py query.py
+./setup.py 1> /dev/null 2>&1
+env keystore=`pwd` ./attr.py 1> attr.log 2>& 1
+
+env keystore=`pwd` ABAC_CN=1 ./query.py 1>likes.tmp 2> likes.time
+
+if [ $noise -eq 0 ] ; then
+    result=`egrep -c "success" likes.tmp 2>/dev/null`
+    if [ $result -eq 202 ]; then
+       echo "   PASSED"
+## zap out all those fake BADs
+       sed -ibak 's/BAD_/fakebad_/g' likes.time
+       exit 0
+    else  
+       echo "   ERROR"
+       exit 1
+    fi
+fi
+
+s=`grep -c "success" likes.tmp 2>/dev/null`
+f=`grep -c "failure" likes.tmp 2>/dev/null `
+if [ $s -ne 101 ] ; then
+    echo "   ERROR"
+    exit 1
+fi
+
+if [ $f  -ne 101 ] ; then
+    echo "   ERROR"
+    exit 1
+fi
+
+echo "   PASSED"
+
