nodes: 0, module; 1, function_definition; 2, function_name:validate_v3_svc_catalog_endpoint_data; 3, parameters; 4, block; 5, identifier:self; 6, identifier:expected; 7, identifier:actual; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, for_statement; 12, return_statement; 13, comment:"""Validate the keystone v3 catalog endpoint data.
  
          Validate a list of dictinaries that make up the keystone v3 service
          catalogue.
  
          It is in the form of:
  
  
          {u'identity': [{u'id': u'48346b01c6804b298cdd7349aadb732e',
                          u'interface': u'admin',
                          u'region': u'RegionOne',
                          u'region_id': u'RegionOne',
                          u'url': u'http://10.5.5.224:35357/v3'},
                         {u'id': u'8414f7352a4b47a69fddd9dbd2aef5cf',
                          u'interface': u'public',
                          u'region': u'RegionOne',
                          u'region_id': u'RegionOne',
                          u'url': u'http://10.5.5.224:5000/v3'},
                         {u'id': u'd5ca31440cc24ee1bf625e2996fb6a5b',
                          u'interface': u'internal',
                          u'region': u'RegionOne',
                          u'region_id': u'RegionOne',
                          u'url': u'http://10.5.5.224:5000/v3'}],
           u'key-manager': [{u'id': u'68ebc17df0b045fcb8a8a433ebea9e62',
                             u'interface': u'public',
                             u'region': u'RegionOne',
                             u'region_id': u'RegionOne',
                             u'url': u'http://10.5.5.223:9311'},
                            {u'id': u'9cdfe2a893c34afd8f504eb218cd2f9d',
                             u'interface': u'internal',
                             u'region': u'RegionOne',
                             u'region_id': u'RegionOne',
                             u'url': u'http://10.5.5.223:9311'},
                            {u'id': u'f629388955bc407f8b11d8b7ca168086',
                             u'interface': u'admin',
                             u'region': u'RegionOne',
                             u'region_id': u'RegionOne',
                             u'url': u'http://10.5.5.223:9312'}]}
  
          Note, that an added complication is that the order of admin, public,
          internal against 'interface' in each region.
  
          Thus, the function sorts the expected and actual lists using the
          interface key as a sort key, prior to the comparison.
          """; 14, call; 15, call; 16, pattern_list; 17, call; 18, block; 19, identifier:ret; 20, attribute; 21, argument_list; 22, attribute; 23, argument_list; 24, identifier:k; 25, identifier:v; 26, attribute; 27, argument_list; 28, if_statement; 29, attribute; 30, identifier:debug; 31, string; 32, attribute; 33, identifier:debug; 34, call; 35, identifier:six; 36, identifier:iteritems; 37, identifier:expected; 38, comparison_operator:k in actual; 39, block; 40, else_clause; 41, identifier:self; 42, identifier:log; 43, string_content:Validating v3 service catalog endpoint data...; 44, identifier:self; 45, identifier:log; 46, attribute; 47, argument_list; 48, identifier:k; 49, identifier:actual; 50, expression_statement; 51, expression_statement; 52, if_statement; 53, for_statement; 54, block; 55, string; 56, identifier:format; 57, call; 58, assignment; 59, assignment; 60, comparison_operator:len(l_actual) != len(l_expected); 61, block; 62, pattern_list; 63, call; 64, block; 65, return_statement; 66, string_content:actual: {}; 67, identifier:repr; 68, argument_list; 69, identifier:l_expected; 70, call; 71, identifier:l_actual; 72, call; 73, call; 74, call; 75, return_statement; 76, identifier:i_expected; 77, identifier:i_actual; 78, identifier:zip; 79, argument_list; 80, expression_statement; 81, expression_statement; 82, if_statement; 83, call; 84, identifier:actual; 85, identifier:sorted; 86, argument_list; 87, identifier:sorted; 88, argument_list; 89, identifier:len; 90, argument_list; 91, identifier:len; 92, argument_list; 93, parenthesized_expression; 94, identifier:l_expected; 95, identifier:l_actual; 96, call; 97, assignment; 98, identifier:ret; 99, block; 100, attribute; 101, argument_list; 102, identifier:v; 103, keyword_argument; 104, subscript; 105, keyword_argument; 106, identifier:l_actual; 107, identifier:l_expected; 108, call; 109, attribute; 110, argument_list; 111, identifier:ret; 112, call; 113, return_statement; 114, string:"endpoint {} does not exist"; 115, identifier:format; 116, identifier:k; 117, identifier:key; 118, lambda; 119, identifier:actual; 120, identifier:k; 121, identifier:key; 122, lambda; 123, attribute; 124, argument_list; 125, attribute; 126, identifier:debug; 127, call; 128, attribute; 129, argument_list; 130, call; 131, lambda_parameters; 132, subscript; 133, lambda_parameters; 134, subscript; 135, concatenated_string; 136, identifier:format; 137, identifier:k; 138, call; 139, call; 140, identifier:self; 141, identifier:log; 142, attribute; 143, argument_list; 144, identifier:self; 145, identifier:_validate_dict_data; 146, identifier:i_expected; 147, identifier:i_actual; 148, attribute; 149, argument_list; 150, identifier:x; 151, identifier:x; 152, string; 153, identifier:x; 154, identifier:x; 155, string; 156, string:"endpoint {} has differing number of interfaces "; 157, string:" - expected({}), actual({})"; 158, identifier:len; 159, argument_list; 160, identifier:len; 161, argument_list; 162, string:"checking interface {}"; 163, identifier:format; 164, subscript; 165, identifier:self; 166, identifier:endpoint_error; 167, identifier:k; 168, identifier:ret; 169, string_content:interface; 170, string_content:interface; 171, identifier:l_expected; 172, identifier:l_actual; 173, identifier:i_expected; 174, string; 175, string_content:interface
code: def validate_v3_svc_catalog_endpoint_data(self, expected, actual):
          """Validate the keystone v3 catalog endpoint data.
  
          Validate a list of dictinaries that make up the keystone v3 service
          catalogue.
  
          It is in the form of:
  
  
          {u'identity': [{u'id': u'48346b01c6804b298cdd7349aadb732e',
                          u'interface': u'admin',
                          u'region': u'RegionOne',
                          u'region_id': u'RegionOne',
                          u'url': u'http://10.5.5.224:35357/v3'},
                         {u'id': u'8414f7352a4b47a69fddd9dbd2aef5cf',
                          u'interface': u'public',
                          u'region': u'RegionOne',
                          u'region_id': u'RegionOne',
                          u'url': u'http://10.5.5.224:5000/v3'},
                         {u'id': u'd5ca31440cc24ee1bf625e2996fb6a5b',
                          u'interface': u'internal',
                          u'region': u'RegionOne',
                          u'region_id': u'RegionOne',
                          u'url': u'http://10.5.5.224:5000/v3'}],
           u'key-manager': [{u'id': u'68ebc17df0b045fcb8a8a433ebea9e62',
                             u'interface': u'public',
                             u'region': u'RegionOne',
                             u'region_id': u'RegionOne',
                             u'url': u'http://10.5.5.223:9311'},
                            {u'id': u'9cdfe2a893c34afd8f504eb218cd2f9d',
                             u'interface': u'internal',
                             u'region': u'RegionOne',
                             u'region_id': u'RegionOne',
                             u'url': u'http://10.5.5.223:9311'},
                            {u'id': u'f629388955bc407f8b11d8b7ca168086',
                             u'interface': u'admin',
                             u'region': u'RegionOne',
                             u'region_id': u'RegionOne',
                             u'url': u'http://10.5.5.223:9312'}]}
  
          Note, that an added complication is that the order of admin, public,
          internal against 'interface' in each region.
  
          Thus, the function sorts the expected and actual lists using the
          interface key as a sort key, prior to the comparison.
          """
          self.log.debug('Validating v3 service catalog endpoint data...')
          self.log.debug('actual: {}'.format(repr(actual)))
          for k, v in six.iteritems(expected):
              if k in actual:
                  l_expected = sorted(v, key=lambda x: x['interface'])
                  l_actual = sorted(actual[k], key=lambda x: x['interface'])
                  if len(l_actual) != len(l_expected):
                      return ("endpoint {} has differing number of interfaces "
                              " - expected({}), actual({})"
                              .format(k, len(l_expected), len(l_actual)))
                  for i_expected, i_actual in zip(l_expected, l_actual):
                      self.log.debug("checking interface {}"
                                     .format(i_expected['interface']))
                      ret = self._validate_dict_data(i_expected, i_actual)
                      if ret:
                          return self.endpoint_error(k, ret)
              else:
                  return "endpoint {} does not exist".format(k)
          return ret