LCOV - code coverage report
Current view: top level - tests - test-multipath.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 42 51 82.4 %
Date: 2016-09-14 01:02:56 Functions: 3 3 100.0 %
Branches: 25 37 67.6 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2010, 2012, 2013, 2014 Nicira, Inc.
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       5                 :            :  * you may not use this file except in compliance with the License.
       6                 :            :  * You may obtain a copy of the License at:
       7                 :            :  *
       8                 :            :  *     http://www.apache.org/licenses/LICENSE-2.0
       9                 :            :  *
      10                 :            :  * Unless required by applicable law or agreed to in writing, software
      11                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :            :  * See the License for the specific language governing permissions and
      14                 :            :  * limitations under the License.
      15                 :            :  */
      16                 :            : 
      17                 :            : #include <config.h>
      18                 :            : #undef NDEBUG
      19                 :            : #include <assert.h>
      20                 :            : #include <getopt.h>
      21                 :            : #include <math.h>
      22                 :            : #include <stdio.h>
      23                 :            : #include <stdlib.h>
      24                 :            : #include "flow.h"
      25                 :            : #include "multipath.h"
      26                 :            : #include "openvswitch/ofp-actions.h"
      27                 :            : #include "ovstest.h"
      28                 :            : #include "util.h"
      29                 :            : 
      30                 :            : static void
      31                 :          4 : test_multipath_main(int argc, char *argv[])
      32                 :            : {
      33                 :            :     enum { MP_MAX_LINKS = 63 };
      34                 :            :     struct ofpact_multipath mp;
      35                 :          4 :     bool ok = true;
      36                 :            :     char *error;
      37                 :            :     int n;
      38                 :            : 
      39                 :          4 :     set_program_name(argv[0]);
      40                 :            : 
      41         [ -  + ]:          4 :     if (argc != 2) {
      42                 :          0 :         ovs_fatal(0, "usage: %s multipath_action", program_name);
      43                 :            :     }
      44                 :            : 
      45                 :          4 :     error = multipath_parse(&mp, argv[1]);
      46         [ -  + ]:          4 :     if (error) {
      47                 :          0 :         ovs_fatal(0, "%s", error);
      48                 :            :     }
      49                 :            : 
      50         [ +  + ]:        256 :     for (n = 1; n <= MP_MAX_LINKS; n++) {
      51                 :            :         enum { N_FLOWS = 65536 };
      52                 :            :         double disruption, perfect, distribution;
      53                 :            :         int histogram[MP_MAX_LINKS];
      54                 :            :         double sum_dev2, stddev;
      55                 :            :         int changed;
      56                 :            :         int i;
      57                 :            : 
      58                 :        252 :         changed = 0;
      59                 :        252 :         memset(histogram, 0, sizeof histogram);
      60         [ +  + ]:   16515324 :         for (i = 0; i < N_FLOWS; i++) {
      61                 :            :             int old_link, new_link;
      62                 :            :             struct flow_wildcards wc;
      63                 :            :             struct flow flow;
      64                 :            : 
      65                 :   16515072 :             flow_random_hash_fields(&flow);
      66                 :            : 
      67                 :   16515072 :             mp.max_link = n - 1;
      68                 :   16515072 :             multipath_execute(&mp, &flow, &wc);
      69                 :   16515072 :             old_link = flow.regs[0];
      70                 :            : 
      71                 :   16515072 :             mp.max_link = n;
      72                 :   16515072 :             multipath_execute(&mp, &flow, &wc);
      73                 :   16515072 :             new_link = flow.regs[0];
      74                 :            : 
      75 [ +  - ][ -  + ]:   16515072 :             assert(old_link >= 0 && old_link < n);
      76 [ +  - ][ -  + ]:   16515072 :             assert(new_link >= 0 && new_link < n + 1);
      77                 :            : 
      78                 :   16515072 :             histogram[old_link]++;
      79                 :   16515072 :             changed += old_link != new_link;
      80                 :            :         }
      81                 :            : 
      82                 :        252 :         sum_dev2 = 0.0;
      83         [ +  + ]:       8316 :         for (i = 0; i < n; i++) {
      84                 :       8064 :             double mean = (double) N_FLOWS / n;
      85                 :       8064 :             double deviation = histogram[i] - mean;
      86                 :            : 
      87                 :       8064 :             sum_dev2 += deviation * deviation;
      88                 :            :         }
      89                 :        252 :         stddev = sqrt(sum_dev2 / n);
      90                 :            : 
      91                 :        252 :         disruption = (double) changed / N_FLOWS;
      92                 :        252 :         perfect = 1.0 / (n + 1);
      93                 :        252 :         distribution = stddev / ((double) N_FLOWS / n);
      94                 :        252 :         printf("%2d -> %2d: disruption=%.2f (perfect=%.2f); "
      95                 :            :                "stddev/expected=%.4f\n",
      96                 :            :                n, n + 1, disruption, perfect, distribution);
      97                 :            : 
      98   [ +  +  +  +  :        252 :         switch (mp.algorithm) {
                      - ]
      99                 :            :         case NX_MP_ALG_MODULO_N:
     100 [ +  + ][ -  + ]:         63 :             if (disruption < (n < 2 ? .25 : .5)) {
     101                 :          0 :                 fprintf(stderr, "%d -> %d: disruption=%.2f < .5\n",
     102                 :            :                         n, n + 1, disruption);
     103                 :          0 :                 ok = false;
     104                 :            :             }
     105                 :         63 :             break;
     106                 :            : 
     107                 :            :         case NX_MP_ALG_HASH_THRESHOLD:
     108 [ +  - ][ -  + ]:         63 :             if (disruption < .48 || disruption > .52) {
     109                 :          0 :                 fprintf(stderr, "%d -> %d: disruption=%.2f not approximately "
     110                 :            :                         ".5\n", n, n + 1, disruption);
     111                 :          0 :                 ok = false;
     112                 :            :             }
     113                 :         63 :             break;
     114                 :            : 
     115                 :            :         case NX_MP_ALG_ITER_HASH:
     116         [ +  + ]:         63 :             if (!(n & (n - 1))) {
     117                 :          6 :                 break;
     118                 :            :             }
     119                 :            :             /* Fall through. */
     120                 :            :         case NX_MP_ALG_HRW:
     121         [ -  + ]:        120 :             if (fabs(disruption - perfect) >= .01) {
     122                 :          0 :                 fprintf(stderr, "%d -> %d: disruption=%.5f differs from "
     123                 :            :                         "perfect=%.5f by more than .01\n",
     124                 :            :                         n, n + 1, disruption, perfect);
     125                 :          0 :                 ok = false;
     126                 :            :             }
     127                 :        120 :             break;
     128                 :            : 
     129                 :            :         default:
     130                 :          0 :             OVS_NOT_REACHED();
     131                 :            :         }
     132                 :            :     }
     133                 :            : 
     134         [ +  - ]:          4 :     exit(ok ? 0 : 1);
     135                 :            : }
     136                 :            : 
     137                 :       1178 : OVSTEST_REGISTER("test-multipath", test_multipath_main);

Generated by: LCOV version 1.12