tests: Change program generating test data
authorJan Cybulski <j.cybulski@samsung.com>
Fri, 7 Feb 2014 13:58:52 +0000 (14:58 +0100)
committerJosé Bollo <jose.bollo@open.eurogiciel.org>
Fri, 14 Feb 2014 14:32:33 +0000 (15:32 +0100)
-Change program to produce more parametrized output:
*Introduce parameters to set number of unique rules (u) and merges in policy (m).
*Introduce parametr for maximum number of reocurrances of a label in merged policy (L).
*Add possibility of getting list of labels from stdin in addition to generating random ones.
-Some minor style adjustments to libsmack coding style.

Also:
-Add makefile for policies generation
-Add script generating different type of policies

Signed-off-by: Jan Cybulski <j.cybulski@samsung.com>
tests/gen.c
tests/make_policies.bash [new file with mode: 0755]
tests/makefile [new file with mode: 0644]

index b65b07a..2d309dc 100644 (file)
@@ -2,25 +2,34 @@
 #include <stdio.h>
 #include <string.h>
 
-int r(int count) {
+struct label {
+       char *label;
+       int counter;
+       char *rules;
+};
+
+int r(int count)
+{
        return random() % count;
 }
 
-int cb(int n) {
+int count_set_bits(int n)
+{
        int result = 0;
-       while(n) {
+       while (n) {
                result += n & 1;
                n >>= 1;
        }
        return result;
 }
 
-int rc(int ref) {
-       int nb = 6 - cb(ref);
+int random_code(int ref)
+{
+       int nb = 6 - count_set_bits(ref);
        int b = r(1 << nb);
        int iter = 1;
        int result = 0;
-       while(nb) {
+       while (nb) {
                if (!(iter & ref)) {
                        if (b & 1)
                                result |= iter;
@@ -32,81 +41,176 @@ int rc(int ref) {
        return result;
 }
 
-void* check(void *ptr) {
-       if(!ptr){
-               fprintf(stderr,"memory depletion!\n");
+void *check_ptr(void *ptr)
+{
+       if (!ptr) {
+               fprintf(stderr, "memory depletion!\n");
                exit(1);
        }
        return ptr;
 }
 
-char** genlabels(int count, int lenmin, int lenmax) {
-       char **result;
+struct label *gen_labels(int count, int lenmin, int lenmax)
+{
+       struct label *result;
+       int i;
+       result = check_ptr(calloc(count, sizeof(struct label)));
+       for (i = 0; i < count; i++) {
+               int len = lenmin + (lenmin == lenmax ? 0 : r(lenmax-lenmin));
+               result[i].label = check_ptr(calloc(1+len, 1));
+               while (len)
+                       result[i].label[--len] = 'A' + (char)(r(26));
+               result[i].rules = check_ptr(calloc(count, sizeof(char)));
+       }
+
+       return result;
+}
+
+struct label *read_labels(int count)
+{
+       struct label *result;
        int i;
-       result = check(calloc(sizeof*result,count));
-       for(i=0;i<count;i++) {
-               int len = lenmin + (lenmin==lenmax ? 0 : r(lenmax-lenmin));
-               result[i] = check(calloc(1+len,1));
-               while(len) result[i][--len] = 'A' + (char)(r(26));
+       size_t tmp;
+
+       result = check_ptr(calloc(count, sizeof(struct label)));
+       for (i = 0; i < count; i++) {
+               tmp = getline(&(result[i].label), &tmp, stdin);
+               result[i].label[tmp-1] = 0;
+               result[i].rules = check_ptr(calloc(count, sizeof(char)));
        }
+
        return result;
 }
 
-int c2s(int code, char *buffer)
+int code_to_string(int code, char *buffer)
 {
        static char *flags = "rwxatl";
        int pos = 0;
        int len = 0;
        while (code) {
-               if (code & 1) buffer[len++] = flags[pos];
+               if (code & 1)
+                       buffer[len++] = flags[pos];
                pos++;
                code >>= 1;
        }
-       if (!len) buffer[len++] = '-';
+       if (!len)
+               buffer[len++] = '-';
        return len;
 }
 
-char** genrights(int count) {
+char **genrights(int count)
+{
        char buffer[20];
        char **result;
        int i;
-       result = check(calloc(sizeof*result,count));
-       for(i=0;i<count;i++) {
-               int allow = rc(0);
-               int len = c2s(allow,buffer);
+       result = check_ptr(calloc(sizeof *result, count));
+       for (i = 0; i < count; i++) {
+               int allow = random_code(0);
+               int len = code_to_string(allow, buffer);
                if (!r(3)) {
                        buffer[len++] = ' ';
-                       len += c2s(rc(allow),buffer+len);
+                       len += code_to_string(random_code(allow), buffer + len);
                }
-               result[i] = check(strndup(buffer,len));
+               result[i] = check_ptr(strndup(buffer, len));
        }
        return result;
 }
 
-int main(int argc, char **argv) {
-       int nlab = 5;
-       int nrig = 100;
-       int nout = 500;
-       char **labels, **rights;
-       while(*++argv) {
+int pick_subj_label(struct label *labels, int nlab, int max_reoccurance)
+{
+       int startidx = r(nlab);
+       int repeat = 0;
+       int idx = startidx;
+       while (labels[idx].counter >= max_reoccurance) {
+               idx++;
+               repeat++;
+               idx %= nlab;
+               if (repeat > nlab) {
+                       fprintf(stderr, "Wrong parameters");
+                       exit(-1);
+               }
+       }
+       return idx;
+}
+
+
+int pick_obj_label(struct label *labels, int nlab, int max_reoccurance, int *subj)
+{
+       int startidx = r(nlab);
+       int repeat = 0;
+       int repeat_subj = 0;
+       int idx = startidx;
+       while (labels[idx].counter >= ((*subj == idx) ? max_reoccurance - 1 : max_reoccurance) ||
+                       labels[*subj].rules[idx] != 0) {
+               idx++;
+               repeat++;
+               idx %= nlab;
+               if (idx == startidx && repeat != 0) {
+                       (*subj)++;
+                       (*subj) %= nlab;
+                       repeat_subj++;
+                       if (repeat_subj > nlab) {
+                               fprintf(stderr, "Wrong parameters");
+                               exit(-1);
+                       } else
+                               repeat = 0;
+               }
+       }
+
+       labels[*subj].counter++;
+       labels[idx].counter++;
+       labels[*subj].rules[idx] = 1;
+       return idx;
+}
+
+int main(int argc, char **argv)
+{
+       int lab_cnt = 500;
+       int rig_cnt = 100;
+       int rul_cnt = 500;
+       int lab_max = rul_cnt * 2;
+       int mer_cnt = 0;
+       int lab_stdin = 0;
+       struct label *labels;
+       char **rights;
+       while (*++argv) {
                char c;
                int n;
-               if (sscanf(*argv,"%1[lro]=%d",&c,&n)==2 && n>0) {
-                       switch(c) {
-                       case 'l': nlab=n; break;
-                       case 'r': nrig=n; break;
-                       case 'o': nout=n; break;
+               if (sscanf(*argv, "%1[lLru]=%d", &c, &n) == 2 && n > 0) {
+                       switch (c) {
+                       case 'l': lab_cnt = n; break;
+                       case 'r': rig_cnt = n; break;
+                       case 'u': rul_cnt = n; break;
+                       case 'L': lab_max = n; break;
                        }
-               }
-               else {
-                       fprintf(stderr,"usage: gen [[lro]=VALUE]... (where VALUE is a number > 0)\n");
+               } else if (sscanf(*argv, "%1[mi]=%d", &c, &n) == 2 && n >= 0) {
+                       switch (c) {
+                       case 'm': mer_cnt = n; break;
+                       case 'i': lab_stdin = n; break;
+                       }
+               } else {
+                       fprintf(stderr, "usage: gen [[lLrumi]=VALUE]... (where VALUE is a number >= 0)\n");
+                       fprintf(stderr, "      l: number of labels in policy, l>0\n");
+                       fprintf(stderr, "      L: maximal number of each label reoccurance in policy, L>0\n");
+                       fprintf(stderr, "      u: number of unique rules (rules with different subject,object pair), u>0\n");
+                       fprintf(stderr, "      m: number of merges per each unique rule, m>=0\n");
+                       fprintf(stderr, "      r: number of different rights generated randomly, r>0\n");
+                       fprintf(stderr, "      i: i=0: generate labels, i>0: read labels from stdio, 0 by default\n");
+
                        exit(1);
                }
        }
-       labels = genlabels(nlab,4,8);
-       rights = genrights(nrig);
-       while(nout--) 
-               printf("%s %s %s\n", labels[r(nlab)], labels[r(nlab)], rights[r(nrig)]);
+       if (lab_stdin)
+               labels = read_labels(lab_cnt);
+       else
+               labels = gen_labels(lab_cnt, 4, 24);
+       rights = genrights(rig_cnt);
+       while (rul_cnt--) {
+               int sub = pick_subj_label(labels, lab_cnt, lab_max);
+               int obj = pick_obj_label(labels, lab_cnt, lab_max, &sub);
+               int i;
+               for (i = 0; i <= mer_cnt; i++)
+                       printf("%s %s %s\n", labels[sub].label, labels[obj].label, rights[r(rig_cnt)]);
+       }
        return 0;
 }
-
diff --git a/tests/make_policies.bash b/tests/make_policies.bash
new file mode 100755 (executable)
index 0000000..9a23cd7
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/bash
+#This script generates smack rule policies with random rules for test purposes.
+
+if [ $# -eq 2 ]
+then
+       test ! -f "$2" && echo "no such file: $2" && exit 1;
+       labs_cnt=`cat "$2" | wc -l`
+       I=i=1
+       in="$2"
+
+elif [ $# -eq 1 ]
+then
+       labs_cnt=1024
+       in=/dev/null
+else
+       echo wrong parameters
+       exit 1
+fi
+
+
+generator="$1"
+outdir=./out/
+test -d "$outdir" || mkdir "$outdir"
+
+#m stands for number of merges per unique subject/object pair in policy
+#number of merges in whole policy would be m*u, u is number of unique rules
+for m in 0 1 2 4 9
+do
+       #power stands for log2 of number of different labels in policy
+       for power in `seq 3 10`
+       do
+               #l stands for number of different labels in policy
+               l=$(echo 2^$power | bc)
+
+               if [ $labs_cnt -ge $l ]
+               then
+                       for type in min 2min log max
+                       do
+                       case $type in
+                       min)  u=$((l/2)); L=1;;#minimal policy (each label occurs only once in policy)
+                       2min) u=$l; L=2;;#another minimal policy (each label occurs twice in policy)
+                       log) u=$((l*power)); L=$((power*2));;#medium sized policy (each label occurs 2log2(l) times in policy)
+                       max) u=$((l*l));L=$((l*2));; #maximally dense policy (each label occurs l*2 times in policy)
+                       esac
+
+                       outfile="$outdir""$type""$l""m$m"
+                       echo generating $outfile
+                       "$generator" l=$l u=$u L=$L m=$m $I < $in | shuf > $outfile
+
+                       #for merged policy make additionally sorted policy
+                       test $m -eq 1 && cat $outfile | sort > "$outdir""$type""$l""sorted" || true
+                       done;
+               fi
+       done
+done
diff --git a/tests/makefile b/tests/makefile
new file mode 100644 (file)
index 0000000..f79cba4
--- /dev/null
@@ -0,0 +1,13 @@
+all: policies
+
+clean:
+       rm -rf ./out ./generator
+
+generator: gen.c
+       gcc gen.c -o ./generator
+
+policies: ./generator ./make_policies.bash
+       ./make_policies.bash ./generator
+
+policies_from_labels: ./generator ./make_policies.bash labels
+       ./make_policies.bash ./generator labels