Skip to content

Commit

Permalink
ref #2150 - add download policy options.
Browse files Browse the repository at this point in the history
  • Loading branch information
jortel committed Dec 2, 2015
1 parent 875d227 commit 6e8ba0c
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 41 deletions.
42 changes: 41 additions & 1 deletion client_lib/pulp/client/commands/repo/importer_config.py
Expand Up @@ -2,6 +2,7 @@

from pulp.client import arg_utils, parsers
from pulp.client.extensions.extensions import PulpCliOption, PulpCliOptionGroup
from pulp.client.validators import download_policy_validator
from pulp.common.plugins import importer_constants as constants


Expand All @@ -11,6 +12,7 @@
GROUP_NAME_PROXY = _('Feed Proxy')
GROUP_NAME_BASIC_AUTH = _('Basic Authentication')
GROUP_NAME_UNIT_POLICY = _('Repository Content Behavior')
GROUP_DOWNLOAD_POLICY = _('Download Policy')


class OptionsBundle(object):
Expand Down Expand Up @@ -96,6 +98,16 @@ def __init__(self):
parse_func=parsers.pulp_parse_optional_nonnegative_int
)

d = _('content downloading policy ({m})'.format(
m=' | '.join((constants.DOWNLOAD_IMMEDIATE,
constants.DOWNLOAD_BACKGROUND,
constants.DOWNLOAD_ON_DEMAND))))
self.opt_download_policy = PulpCliOption(
'--download-policy',
d,
validate_func=download_policy_validator,
required=False)


class ImporterConfigMixin(object):
"""
Expand Down Expand Up @@ -134,7 +146,8 @@ def __init__(self,
include_proxy=True,
include_basic_auth=False,
include_throttling=True,
include_unit_policy=True):
include_unit_policy=True,
include_download_policy=False):

# If the caller didn't dork with any of the options, instantiate one with the defaults
self.options_bundle = options_bundle or OptionsBundle()
Expand All @@ -147,6 +160,7 @@ def __init__(self,
self.basic_auth_group = PulpCliOptionGroup(GROUP_NAME_BASIC_AUTH)
self.throttling_group = PulpCliOptionGroup(GROUP_NAME_THROTTLING)
self.unit_policy_group = PulpCliOptionGroup(GROUP_NAME_UNIT_POLICY)
self.download_policy_group = PulpCliOptionGroup(GROUP_DOWNLOAD_POLICY)

if include_sync:
self.populate_sync_group()
Expand All @@ -172,6 +186,10 @@ def __init__(self,
self.populate_unit_policy()
self.add_option_group(self.unit_policy_group)

if include_download_policy:
self.populate_download_policy()
self.add_option_group(self.download_policy_group)

def populate_sync_group(self):
"""
Adds options to the synchronization group. This is only called if the include_sync flag is
Expand Down Expand Up @@ -224,6 +242,13 @@ def populate_unit_policy(self):
self.unit_policy_group.add_option(self.options_bundle.opt_remove_missing)
self.unit_policy_group.add_option(self.options_bundle.opt_retain_old_count)

def populate_download_policy(self):
"""
Adds options to the download policy group. This is only called if the
include_download_policy flag is set to True in the constructor.
"""
self.download_policy_group.add_option(self.options_bundle.opt_download_policy)

def parse_user_input(self, user_input):
"""
Reads the user input for any specified values that correspond to the importer config
Expand All @@ -247,6 +272,7 @@ def parse_user_input(self, user_input):
config.update(self.parse_proxy_group(user_input))
config.update(self.parse_throttling_group(user_input))
config.update(self.parse_unit_policy(user_input))
config.update(self.parse_download_policy(user_input))
return config

def parse_sync_group(self, user_input):
Expand Down Expand Up @@ -379,6 +405,20 @@ def parse_unit_policy(self, user_input):
safe_parse(user_input, config, input_key, config_key)
return config

def parse_download_policy(self, user_input):
"""
Reads download policy related config options from the user input and packages them into
the Pulp standard importer config format.
"""
key_tuples = (
(constants.DOWNLOAD_POLICY, self.options_bundle.opt_download_policy.keyword),
)

config = {}
for config_key, input_key in key_tuples:
safe_parse(user_input, config, input_key, config_key)
return config


def safe_parse(user_input, config, input_keyword, config_keyword):
"""
Expand Down
18 changes: 18 additions & 0 deletions client_lib/pulp/client/validators.py
Expand Up @@ -8,6 +8,7 @@
from gettext import gettext as _

from pulp.common import dateutils
from pulp.common.plugins import importer_constants


ID_REGEX_ALLOW_DOTS = re.compile(r'^[.\-_A-Za-z0-9]+$')
Expand Down Expand Up @@ -116,3 +117,20 @@ def id_validator_allow_dots(x):
if ID_REGEX_ALLOW_DOTS.match(input_id) is None:
raise ValueError(_('value must contain only letters, numbers, underscores, periods and '
'hyphens'))


def download_policy_validator(x):
"""
Download policy validator.
:param x: input value to be validated
:type x: str or list
:raise ValueError: if the input is not a valid policy.
"""
valid = (
importer_constants.DOWNLOAD_IMMEDIATE,
importer_constants.DOWNLOAD_BACKGROUND,
importer_constants.DOWNLOAD_ON_DEMAND)
if x not in valid:
raise ValueError(_('policy must be: ({p})'.format(p=' | '.join(valid))))
41 changes: 27 additions & 14 deletions client_lib/test/unit/test_commands_importer_config.py
Expand Up @@ -17,16 +17,19 @@ class MixinTest(PulpCliCommand, importer_config.ImporterConfigMixin):
"""

def __init__(self, options_bundle=None, include_sync=True, include_ssl=True, include_proxy=True,
include_throttling=True, include_unit_policy=True, include_basic_auth=True):
include_throttling=True, include_unit_policy=True, include_basic_auth=True,
include_download_policy=True):
PulpCliCommand.__init__(self, 'mixin', '', self.run)
importer_config.ImporterConfigMixin.__init__(self,
options_bundle=options_bundle,
include_sync=include_sync,
include_ssl=include_ssl,
include_proxy=include_proxy,
include_basic_auth=include_basic_auth,
include_throttling=include_throttling,
include_unit_policy=include_unit_policy)
importer_config.ImporterConfigMixin.__init__(
self,
options_bundle=options_bundle,
include_sync=include_sync,
include_ssl=include_ssl,
include_proxy=include_proxy,
include_basic_auth=include_basic_auth,
include_throttling=include_throttling,
include_unit_policy=include_unit_policy,
include_download_policy=include_download_policy)

self.last_parsed_config = None

Expand Down Expand Up @@ -54,18 +57,21 @@ def test_groups(self):
tested separately.
"""

self.assertEqual(6, len(self.mixin.option_groups))
self.assertEqual(7, len(self.mixin.option_groups))
group_names = [g.name for g in self.mixin.option_groups]
expected_names = [importer_config.GROUP_NAME_SYNC, importer_config.GROUP_NAME_SSL,
importer_config.GROUP_NAME_PROXY, importer_config.GROUP_NAME_THROTTLING,
expected_names = [importer_config.GROUP_NAME_SYNC,
importer_config.GROUP_NAME_SSL,
importer_config.GROUP_NAME_PROXY,
importer_config.GROUP_NAME_THROTTLING,
importer_config.GROUP_NAME_UNIT_POLICY,
importer_config.GROUP_NAME_BASIC_AUTH]
importer_config.GROUP_NAME_BASIC_AUTH,
importer_config.GROUP_DOWNLOAD_POLICY]
self.assertEqual(set(group_names), set(expected_names))

def test_groups_no_includes(self):
self.mixin = MixinTest(include_sync=False, include_ssl=False, include_proxy=False,
include_throttling=False, include_unit_policy=False,
include_basic_auth=False)
include_basic_auth=False, include_download_policy=False)
self.assertEqual(0, len(self.mixin.option_groups))

# -- populate tests -------------------------------------------------------
Expand Down Expand Up @@ -189,6 +195,13 @@ def test_parse_throttling(self):
self.assertEqual(parsed['max_downloads'], 4)
self.assertEqual(parsed['max_speed'], 1024)

def test_parse_download_policy_group(self):
user_input = {
self.mixin.options_bundle.opt_download_policy.keyword: constants.DOWNLOAD_BACKGROUND
}
parsed = self.mixin.parse_download_policy(user_input)
self.assertEqual(parsed[constants.DOWNLOAD_POLICY], constants.DOWNLOAD_BACKGROUND)

def test_end_to_end(self):
# Setup
self.cli.add_command(self.mixin)
Expand Down
15 changes: 15 additions & 0 deletions client_lib/test/unit/test_validators.py
@@ -1,6 +1,7 @@
import unittest

from pulp.client import validators
from pulp.common.plugins import importer_constants


class TestPositiveInt(unittest.TestCase):
Expand Down Expand Up @@ -136,3 +137,17 @@ def test_invalid_ids_allow_dots(self):
# Multiple input
self.assertRaises(ValueError, validators.id_validator_allow_dots, ['**invalid**', '!#$%'])
self.assertRaises(ValueError, validators.id_validator_allow_dots, ['valid', '**invalid**'])


class TestDownloadPolicyValidator(unittest.TestCase):

def test_valid(self):
valid = (
importer_constants.DOWNLOAD_IMMEDIATE,
importer_constants.DOWNLOAD_BACKGROUND,
importer_constants.DOWNLOAD_ON_DEMAND)
for policy in valid:
validators.download_policy_validator(policy)

def test_invalid(self):
self.assertRaises(ValueError, validators.download_policy_validator, '1234')
16 changes: 8 additions & 8 deletions common/pulp/common/plugins/importer_constants.py
Expand Up @@ -80,11 +80,11 @@
KEY_UNITS_RETAIN_OLD_COUNT = 'retain_old_count'


# Lazy
# DISABLED - Content is downloaded immediately.
# ACTIVE - Content is downloaded in the background.
# PASSIVE - Content is downloaded on demand.
LAZY_DISABLED = None
LAZY_ACTIVE = 'active'
LAZY_PASSIVE = 'passive'
LAZY_MODE = 'lazy_mode'
# Download policy (Lazy)
# IMMEDIATE - Content is downloaded immediately.
# BACKGROUND - Content is downloaded in the background.
# ON_DEMAND - Content is downloaded on demand.
DOWNLOAD_IMMEDIATE = 'immediate'
DOWNLOAD_ON_DEMAND = 'on_demand'
DOWNLOAD_BACKGROUND = 'background'
DOWNLOAD_POLICY = 'download_policy'
16 changes: 8 additions & 8 deletions server/pulp/plugins/util/importer_config.py
Expand Up @@ -363,20 +363,20 @@ def validate_retain_old_count(config):
raise ValueError(msg)


def validate_lazy_mode(config):
def validate_download_policy(config):
"""
Validate lazy content modes.
Validate download policy.
:param config: A configuration.
:type config: pulp.plugins.config.PluginCallConfiguration
:raise ValueError: on failed.
"""
key = importer_constants.LAZY_MODE
lazy = config.get(key)
key = importer_constants.DOWNLOAD_POLICY
lazy = config.get(key, importer_constants.DOWNLOAD_IMMEDIATE)
modes = [
importer_constants.LAZY_DISABLED,
importer_constants.LAZY_ACTIVE,
importer_constants.LAZY_PASSIVE
importer_constants.DOWNLOAD_IMMEDIATE,
importer_constants.DOWNLOAD_BACKGROUND,
importer_constants.DOWNLOAD_ON_DEMAND
]
if lazy not in modes:
raise ValueError(_('{k} must be: {m}').format(k=key, m=modes))
Expand Down Expand Up @@ -445,5 +445,5 @@ def _run_validate_is_non_required_bool(config, setting_name):
validate_validate_downloads,
validate_remove_missing,
validate_retain_old_count,
validate_lazy_mode,
validate_download_policy,
)
20 changes: 10 additions & 10 deletions server/test/unit/plugins/util/test_importer_config.py
Expand Up @@ -472,29 +472,29 @@ def test_non_positive_str(self):
self.assertTrue('-1' in e[0])


class TestLazyMode(unittest.TestCase):
class TestDownloadPolicy(unittest.TestCase):

def test_valid(self):
# not specified
config = PluginCallConfiguration({}, {})
importer_config.validate_lazy_mode(config)
importer_config.validate_download_policy(config)
# off
config = PluginCallConfiguration(
{importer_constants.LAZY_MODE: importer_constants.LAZY_DISABLED}, {})
importer_config.validate_lazy_mode(config)
{importer_constants.DOWNLOAD_POLICY: importer_constants.DOWNLOAD_IMMEDIATE}, {})
importer_config.validate_download_policy(config)
# active
config = PluginCallConfiguration(
{importer_constants.LAZY_MODE: importer_constants.LAZY_ACTIVE}, {})
importer_config.validate_lazy_mode(config)
{importer_constants.DOWNLOAD_POLICY: importer_constants.DOWNLOAD_BACKGROUND}, {})
importer_config.validate_download_policy(config)
# passive
config = PluginCallConfiguration(
{importer_constants.LAZY_MODE: importer_constants.LAZY_PASSIVE}, {})
importer_config.validate_lazy_mode(config)
{importer_constants.DOWNLOAD_POLICY: importer_constants.DOWNLOAD_ON_DEMAND}, {})
importer_config.validate_download_policy(config)

def test_invalid(self):
config = PluginCallConfiguration(
{importer_constants.LAZY_MODE: 'This is bad'}, {})
self.assertRaises(ValueError, importer_config.validate_lazy_mode, config)
{importer_constants.DOWNLOAD_POLICY: 'This is bad'}, {})
self.assertRaises(ValueError, importer_config.validate_download_policy, config)


class ValidateIsNonRequiredBooleanTests(unittest.TestCase):
Expand Down

0 comments on commit 6e8ba0c

Please sign in to comment.