LCOV - code coverage report
Current view: top level - datasrc - memory_datasrc_link.cc (source / functions) Hit Total Coverage
Test: report.info Lines: 42 57 73.7 %
Date: 2012-05-15 Functions: 6 7 85.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 81 170 47.6 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
       2                 :            : //
       3                 :            : // Permission to use, copy, modify, and/or distribute this software for any
       4                 :            : // purpose with or without fee is hereby granted, provided that the above
       5                 :            : // copyright notice and this permission notice appear in all copies.
       6                 :            : //
       7                 :            : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
       8                 :            : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
       9                 :            : // AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
      10                 :            : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
      11                 :            : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
      12                 :            : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
      13                 :            : // PERFORMANCE OF THIS SOFTWARE.
      14                 :            : 
      15                 :            : #include <cc/data.h>
      16                 :            : 
      17                 :            : #include <dns/rrclass.h>
      18                 :            : 
      19                 :            : #include <datasrc/client.h>
      20                 :            : #include <datasrc/memory_datasrc.h>
      21                 :            : 
      22                 :            : #include <boost/foreach.hpp>
      23                 :            : 
      24                 :            : #include <string>
      25                 :            : 
      26                 :            : using namespace isc::dns;
      27                 :            : using namespace isc::data;
      28                 :            : 
      29                 :            : namespace isc {
      30                 :            : namespace datasrc {
      31                 :            : 
      32                 :            : namespace {
      33                 :            : // convencience function to add an error message to a list of those
      34                 :            : // (TODO: move functions like these to some util lib?)
      35                 :            : void
      36                 :         31 : addError(ElementPtr errors, const std::string& error) {
      37 [ +  - ][ -  + ]:         62 :     if (errors != ElementPtr() && errors->getType() == Element::list) {
                 [ +  - ]
      38         [ +  - ]:         62 :         errors->add(Element::create(error));
      39                 :            :     }
      40                 :         31 : }
      41                 :            : 
      42                 :            : /// Check if the given element exists in the map, and if it is a string
      43                 :            : bool
      44                 :         30 : checkConfigElementString(ConstElementPtr config, const std::string& name,
      45                 :            :                          ElementPtr errors)
      46                 :            : {
      47         [ +  + ]:         30 :     if (!config->contains(name)) {
      48                 :            :         addError(errors,
      49                 :            :                  "Config for memory backend does not contain a '"
      50                 :         10 :                  +name+
      51 [ +  - ][ +  - ]:         30 :                  "' value");
      52                 :         10 :         return false;
      53         [ +  - ]:         58 :     } else if (!config->get(name) ||
           [ +  +  +  + ]
         [ +  + ][ #  # ]
      54 [ +  - ][ +  + ]:         38 :                config->get(name)->getType() != Element::string) {
      55                 :          4 :         addError(errors, "value of " + name +
      56 [ +  - ][ +  - ]:         12 :                  " in memory backend config is not a string");
      57                 :         30 :         return false;
      58                 :            :     } else {
      59                 :            :         return true;
      60                 :            :     }
      61                 :            : }
      62                 :            : 
      63                 :            : bool
      64                 :          0 : checkZoneConfig(ConstElementPtr config, ElementPtr errors) {
      65                 :          0 :     bool result = true;
      66 [ #  # ][ #  # ]:          0 :     if (!config || config->getType() != Element::map) {
                 [ #  # ]
      67         [ #  # ]:          0 :         addError(errors, "Elements in memory backend's zone list must be maps");
      68                 :            :         result = false;
      69                 :            :     } else {
      70 [ #  # ][ #  # ]:          0 :         if (!checkConfigElementString(config, "origin", errors)) {
                 [ #  # ]
      71                 :          0 :             result = false;
      72                 :            :         }
      73 [ #  # ][ #  # ]:          0 :         if (!checkConfigElementString(config, "file", errors)) {
                 [ #  # ]
      74                 :          0 :             result = false;
      75                 :            :         }
      76                 :            :         // we could add some existence/readabilty/parsability checks here
      77                 :            :         // if we want
      78                 :            :     }
      79                 :          0 :     return result;
      80                 :            : }
      81                 :            : 
      82                 :            : bool
      83                 :         17 : checkConfig(ConstElementPtr config, ElementPtr errors) {
      84                 :            :     /* Specific configuration is under discussion, right now this accepts
      85                 :            :      * the 'old' configuration, see [TODO]
      86                 :            :      * So for memory datasource, we get a structure like this:
      87                 :            :      * { "type": string ("memory"),
      88                 :            :      *   "class": string ("IN"/"CH"/etc),
      89                 :            :      *   "zones": list
      90                 :            :      * }
      91                 :            :      * Zones list is a list of maps:
      92                 :            :      * { "origin": string,
      93                 :            :      *     "file": string
      94                 :            :      * }
      95                 :            :      *
      96                 :            :      * At this moment we cannot be completely sure of the contents of the
      97                 :            :      * structure, so we have to do some more extensive tests than should
      98                 :            :      * strictly be necessary (e.g. existence and type of elements)
      99                 :            :      */
     100                 :         17 :     bool result = true;
     101                 :            : 
     102 [ +  + ][ +  + ]:         17 :     if (!config || config->getType() != Element::map) {
                 [ +  + ]
     103         [ +  - ]:          6 :         addError(errors, "Base config for memory backend must be a map");
     104                 :            :         result = false;
     105                 :            :     } else {
     106 [ +  - ][ +  - ]:         60 :         if (!checkConfigElementString(config, "type", errors)) {
                 [ +  + ]
     107                 :            :             result = false;
     108                 :            :         } else {
     109 [ +  - ][ +  - ]:         30 :             if (config->get("type")->stringValue() != "memory") {
                 [ +  + ]
     110                 :            :                 addError(errors,
     111         [ +  - ]:          3 :                          "Config for memory backend is not of type \"memory\"");
     112                 :            :                 result = false;
     113                 :            :             }
     114                 :            :         }
     115 [ +  - ][ +  - ]:         60 :         if (!checkConfigElementString(config, "class", errors)) {
                 [ +  + ]
     116                 :            :             result = false;
     117                 :            :         } else {
     118                 :            :             try {
     119 [ +  - ][ +  - ]:         12 :                 RRClass rrc(config->get("class")->stringValue());
         [ +  - ][ +  + ]
     120         [ -  + ]:          2 :             } catch (const isc::Exception& rrce) {
     121                 :            :                 addError(errors,
     122                 :            :                          "Error parsing class config for memory backend: " +
     123 [ -  + ][ -  + ]:          3 :                          std::string(rrce.what()));
                 [ -  + ]
     124                 :          1 :                 result = false;
     125                 :            :             }
     126                 :            :         }
     127 [ +  - ][ +  + ]:         15 :         if (!config->contains("zones")) {
     128         [ +  - ]:         33 :             addError(errors, "No 'zones' element in memory backend config");
     129                 :            :             result = false;
     130 [ +  - ][ +  - ]:         11 :         } else if (!config->get("zones") ||
           [ +  +  +  + ]
         [ +  + ][ #  # ]
                 [ #  # ]
     131 [ +  - ][ +  - ]:         10 :                    config->get("zones")->getType() != Element::list) {
         [ +  + ][ +  + ]
                 [ #  # ]
     132         [ +  - ]:          6 :             addError(errors, "'zones' element in memory backend config is not a list");
     133                 :            :             result = false;
     134                 :            :         } else {
     135 [ +  - ][ +  - ]:          4 :             BOOST_FOREACH(ConstElementPtr zone_config,
           [ #  #  #  # ]
         [ +  - ][ +  - ]
                 [ -  + ]
     136                 :            :                           config->get("zones")->listValue()) {
     137 [ #  # ][ #  # ]:          0 :                 if (!checkZoneConfig(zone_config, errors)) {
     138                 :          0 :                     result = false;
     139                 :            :                 }
     140                 :            :             }
     141                 :            :         }
     142                 :            :     }
     143                 :            : 
     144                 :         17 :     return (result);
     145                 :            : }
     146                 :            : 
     147                 :            : } // end unnamed namespace
     148                 :            : 
     149                 :            : DataSourceClient *
     150                 :         17 : createInstance(isc::data::ConstElementPtr config, std::string& error) {
     151                 :         17 :     ElementPtr errors(Element::createList());
     152 [ +  - ][ +  + ]:         34 :     if (!checkConfig(config, errors)) {
     153 [ +  - ][ +  - ]:         30 :         error = "Configuration error: " + errors->str();
     154                 :            :         return (NULL);
     155                 :            :     }
     156                 :            :     try {
     157 [ +  - ][ +  - ]:          2 :         return (new isc::datasrc::InMemoryClient());
     158                 :          0 :     } catch (const std::exception& exc) {
     159 [ #  # ][ #  # ]:          0 :         error = std::string("Error creating memory datasource: ") + exc.what();
     160                 :            :         return (NULL);
     161 [ #  # ][ #  # ]:          0 :     } catch (...) {
     162                 :            :         error = std::string("Error creating memory datasource, "
     163         [ #  # ]:          0 :                             "unknown exception");
     164                 :            :         return (NULL);
     165                 :            :     }
     166                 :            : }
     167                 :            : 
     168                 :          2 : void destroyInstance(DataSourceClient* instance) {
     169         [ +  - ]:          2 :     delete instance;
     170                 :          2 : }
     171                 :            : 
     172                 :            : } // end of namespace datasrc
     173                 :          2 : } // end of namespace isc

Generated by: LCOV version 1.9