random: Add entropy test.
authorBen Pfaff <blp@nicira.com>
Mon, 15 Nov 2010 17:34:18 +0000 (09:34 -0800)
committerBen Pfaff <blp@nicira.com>
Mon, 15 Nov 2010 17:34:18 +0000 (09:34 -0800)
This test would have made the bug fixed in the previous commit obvious.  It
would have printed the following:

average=0007c220

bit      0     1
  0  5012  4988
  1  5019  4981
  2  5154  4846
  3  4909  5091
  4  5011  4989
  5  5021  4979
  6  4911  5089
  7  4910  5090
  8  5011  4989
  9  5020  4980
 10  5154  4846
 11  5021  4979
 12  5155  4845
 13  5019  4981
 14  5153  4847
 15  5153  4847
 16  5153  4847
 17  5153  4847
 18  5153  4847
 19  5152  4848
 20 10000     0
 21 10000     0
 22 10000     0
 23 10000     0
 24 10000     0
 25 10000     0
 26 10000     0
 27 10000     0
 28 10000     0
 29 10000     0
 30 10000     0
 31 10000     0
(expected values are 5000)

nibble   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
     0 696 646 564 693 542 545 612 611 687 663 645 560 674 566 592 704
     1 625 589 597 571 638 623 604 663 670 652 650 557 541 683 686 651
     2 628 644 659 672 648 569 585 616 623 647 681 600 586 675 601 566
     3 683 665 717 549 633 613 701 592 663 531 545 800 623 608 590 487
     4 622 657 777 557 720 608 613 598 657 678 551 654 615 596 598 499
     5 10000   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
     6 10000   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
     7 10000   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
(expected values are 625)

lib/random.c
lib/random.h
tests/automake.mk
tests/library.at
tests/test-random.c [new file with mode: 0644]

index 7f892514ce09534842984cf8856698be06d7162c..6b02446014e1f71eb778f3c047fe43ee563ee6f2 100644 (file)
@@ -17,6 +17,7 @@
 #include <config.h>
 #include "random.h"
 
+#include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <sys/time.h>
@@ -56,6 +57,13 @@ random_init(void)
     }
 }
 
+void
+random_set_seed(uint32_t seed_)
+{
+    assert(seed_);
+    seed = seed_;
+}
+
 void
 random_bytes(void *p_, size_t n)
 {
index 198adeabfa68d8be11def6fc5397b346f17ecedd..c698638597a4977f334b98dbce02d1c47d3e21d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010 Nicira Networks.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,8 @@
 #include <stdint.h>
 
 void random_init(void);
+void random_set_seed(uint32_t);
+
 void random_bytes(void *, size_t);
 uint8_t random_uint8(void);
 uint16_t random_uint16(void);
index 0bac3516498fd76072ffe1258fc0f68763ea9cfd..8503b6c3f1bf38b8633a26a4e7368efdf92b6ac7 100644 (file)
@@ -74,6 +74,7 @@ lcov_wrappers = \
        tests/lcov/test-list \
        tests/lcov/test-lockfile \
        tests/lcov/test-ovsdb \
+       tests/lcov/test-random \
        tests/lcov/test-reconnect \
        tests/lcov/test-sha1 \
        tests/lcov/test-timeval \
@@ -124,6 +125,7 @@ valgrind_wrappers = \
        tests/valgrind/test-list \
        tests/valgrind/test-lockfile \
        tests/valgrind/test-ovsdb \
+       tests/valgrind/test-random \
        tests/valgrind/test-reconnect \
        tests/valgrind/test-sha1 \
        tests/valgrind/test-timeval \
@@ -216,6 +218,10 @@ noinst_PROGRAMS += tests/test-lockfile
 tests_test_lockfile_SOURCES = tests/test-lockfile.c
 tests_test_lockfile_LDADD = lib/libopenvswitch.a
 
+noinst_PROGRAMS += tests/test-random
+tests_test_random_SOURCES = tests/test-random.c
+tests_test_random_LDADD = lib/libopenvswitch.a
+
 noinst_PROGRAMS += tests/test-unix-socket
 tests_test_unix_socket_SOURCES = tests/test-unix-socket.c
 tests_test_unix_socket_LDADD = lib/libopenvswitch.a
index cab8e2c9be45cb4815d4853c0332623b4a762100..418b279753e81ef9fa1d079997b071120493ebfd 100644 (file)
@@ -39,6 +39,58 @@ AT_KEYWORDS([byte order])
 AT_CHECK([test-byte-order], [0], [ignore])
 AT_CLEANUP
 
+AT_SETUP([test random number generator])
+AT_CHECK([test-random], [0], [dnl
+average=7fa2014f
+
+bit      0     1
+  0  4946  5054
+  1  4939  5061
+  2  4947  5053
+  3  4935  5065
+  4  5004  4996
+  5  4998  5002
+  6  5062  4938
+  7  5009  4991
+  8  5001  4999
+  9  5022  4978
+ 10  5006  4994
+ 11  5039  4961
+ 12  4940  5060
+ 13  5048  4952
+ 14  4930  5070
+ 15  4973  5027
+ 16  4954  5046
+ 17  5043  4957
+ 18  5020  4980
+ 19  5104  4896
+ 20  5051  4949
+ 21  5003  4997
+ 22  5110  4890
+ 23  4950  5050
+ 24  5016  4984
+ 25  5019  4981
+ 26  4948  5052
+ 27  4995  5005
+ 28  4995  5005
+ 29  4969  5031
+ 30  5109  4891
+ 31  4984  5016
+(expected values are 5000)
+
+nibble   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
+     0 640 589 610 613 588 632 650 613 582 646 627 640 612 650 637 671
+     1 626 642 663 620 630 609 617 602 615 638 614 644 641 597 598 644
+     2 667 611 617 613 609 629 642 651 604 641 594 659 651 610 617 585
+     3 621 662 594 605 618 644 616 613 613 616 611 608 614 660 653 652
+     4 641 668 621 664 619 624 625 642 624 629 607 566 599 639 618 614
+     5 666 629 620 621 581 615 598 620 630 651 671 622 628 603 657 588
+     6 620 640 621 606 603 644 628 633 620 597 653 591 637 658 634 615
+     7 636 645 679 593 598 609 612 612 623 626 638 669 603 629 606 622
+(expected values are 625)
+])
+AT_CLEANUP
+
 AT_SETUP([test unix socket -- short pathname])
 AT_CHECK([test-unix-socket x])
 AT_CLEANUP
diff --git a/tests/test-random.c b/tests/test-random.c
new file mode 100644 (file)
index 0000000..9fcc632
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2008, 2009, 2010 Nicira Networks.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+
+#include "random.h"
+
+#include <stdio.h>
+#include <string.h>
+
+int
+main(void)
+{
+    enum { N_ROUNDS = 10000 };
+    unsigned long long int total;
+    int hist16[8][16];
+    int hist2[32];
+    int i;
+
+    random_set_seed(1);
+
+    total = 0;
+    memset(hist2, 0, sizeof hist2);
+    memset(hist16, 0, sizeof hist16);
+    for (i = 0; i < N_ROUNDS; i++) {
+        uint32_t x;
+        int j;
+
+        x = random_uint32();
+
+        total += x;
+
+        for (j = 0; j < 32; j++) {
+            if (x & (1u << j)) {
+                hist2[j]++;
+            }
+        }
+
+        for (j = 0; j < 8; j++) {
+            hist16[j][(x >> (j * 4)) & 15]++;
+        }
+    }
+
+    printf("average=%08llx\n", total / N_ROUNDS);
+
+    printf("\nbit      0     1\n");
+    for (i = 0; i < 32; i++) {
+        printf("%3d %5d %5d\n", i, N_ROUNDS - hist2[i], hist2[i]);
+    }
+    printf("(expected values are %d)\n", N_ROUNDS / 2);
+
+    printf("\nnibble   0   1   2   3   4   5   6   7   8   9  10  11  12  "
+           "13  14  15\n");
+    for (i = 0; i < 8; i++) {
+        int j;
+
+        printf("%6d", i);
+        for (j = 0; j < 16; j++) {
+            printf(" %3d", hist16[i][j]);
+        }
+        printf("\n");
+    }
+    printf("(expected values are %d)\n", N_ROUNDS / 16);
+
+    return 0;
+}