<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def validate_config_data(self, sentry_unit, config_file, section, expected):
 """Validate config file data. Verify that the specified section of the config file contains the expected option key:value pairs. Compare expected dictionary data vs actual dictionary data. The values in the 'expected' dictionary can be strings, bools, ints, longs, or can be a function that evaluates a variable and returns a bool. """

        self.log.debug('Validating config file data ({} in {} on {})'
                       '...'.format(section, config_file,
                                    sentry_unit.info['unit_name']))
        config = self._get_config(sentry_unit, config_file)

        if section != 'DEFAULT' and not config.has_section(section):
            return "section [{}] does not exist".format(section)

        for k in expected.keys():
            if not config.has_option(section, k):
                return "section [{}] is missing option {}".format(section, k)

            actual = config.get(section, k)
            v = expected[k]
            if (isinstance(v, six.string_types) or
                    isinstance(v, bool) or
                    isinstance(v, six.integer_types)):
                # handle explicit values
                if actual != v:
                    return "section [{}] {}:{} != expected {}:{}".format(
                           section, k, actual, k, expected[k])
            # handle function pointers, such as not_null or valid_ip
            elif not v(actual):
                return "section [{}] {}:{} != expected {}:{}".format(
                       section, k, actual, k, expected[k])
        return None