aurora-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject incubator-aurora git commit: Splitting cron and non-cron job creation in client v2.
Date Fri, 14 Nov 2014 02:00:23 GMT
Repository: incubator-aurora
Updated Branches:
  refs/heads/master 254e175ea -> 4d4b41aaf


Splitting cron and non-cron job creation in client v2.

Bugs closed: AURORA-917

Reviewed at https://reviews.apache.org/r/27747/


Project: http://git-wip-us.apache.org/repos/asf/incubator-aurora/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-aurora/commit/4d4b41aa
Tree: http://git-wip-us.apache.org/repos/asf/incubator-aurora/tree/4d4b41aa
Diff: http://git-wip-us.apache.org/repos/asf/incubator-aurora/diff/4d4b41aa

Branch: refs/heads/master
Commit: 4d4b41aaf832d48fb82c744e172f1ebac6b88b17
Parents: 254e175
Author: Maxim Khutornenko <maxim@apache.org>
Authored: Thu Nov 13 18:00:00 2014 -0800
Committer: Maxim Khutornenko <maxim@apache.org>
Committed: Thu Nov 13 18:00:00 2014 -0800

----------------------------------------------------------------------
 .../thrift/SchedulerThriftInterface.java        | 15 ++++--
 .../python/apache/aurora/client/cli/cron.py     | 26 +++++++---
 .../python/apache/aurora/client/cli/jobs.py     | 45 ++++++++++--------
 .../thrift/SchedulerThriftInterfaceTest.java    | 24 ++++++++--
 .../apache/aurora/client/cli/test_create.py     | 15 ++++++
 .../apache/aurora/client/cli/test_cron.py       | 25 ++++++++--
 .../python/apache/aurora/client/cli/util.py     | 50 ++++++++++++++++++--
 7 files changed, 157 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/4d4b41aa/src/main/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterface.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterface.java
b/src/main/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterface.java
index b2b66ac..f081bf3 100644
--- a/src/main/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterface.java
+++ b/src/main/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterface.java
@@ -356,8 +356,7 @@ class SchedulerThriftInterface implements AuroraAdmin.Iface {
           Optional.fromNullable(mutableLock).transform(ILock.FROM_BUILDER));
 
       if (!sanitized.isCron()) {
-        LOG.info("Invalid attempt to schedule non-cron job " + jobKey + " with cron.");
-        return invalidResponse("Job " + jobKey + " has no cron schedule");
+        return invalidResponse(noCronScheduleMessage(jobKey));
       }
 
       ITaskConfig template = sanitized.getJobConfig().getTaskConfig();
@@ -396,7 +395,7 @@ class SchedulerThriftInterface implements AuroraAdmin.Iface {
           Optional.fromNullable(mutableLock).transform(ILock.FROM_BUILDER));
 
       if (!cronJobManager.deleteJob(jobKey)) {
-        return invalidResponse("Job " + jobKey + " is not scheduled with cron");
+        return invalidResponse(notScheduledCronMessage(jobKey));
       }
       return okEmptyResponse();
     } catch (AuthFailedException e) {
@@ -1570,6 +1569,16 @@ class SchedulerThriftInterface implements AuroraAdmin.Iface {
   }
 
   @VisibleForTesting
+  static String noCronScheduleMessage(IJobKey jobKey) {
+    return String.format("Job %s has no cron schedule", JobKeys.canonicalString(jobKey));
+  }
+
+  @VisibleForTesting
+  static String notScheduledCronMessage(IJobKey jobKey) {
+    return String.format("Job %s is not scheduled with cron", JobKeys.canonicalString(jobKey));
+  }
+
+  @VisibleForTesting
   static final String NO_TASKS_TO_KILL_MESSAGE = "No tasks to kill.";
 
   @VisibleForTesting

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/4d4b41aa/src/main/python/apache/aurora/client/cli/cron.py
----------------------------------------------------------------------
diff --git a/src/main/python/apache/aurora/client/cli/cron.py b/src/main/python/apache/aurora/client/cli/cron.py
index 44c066b..cfd957c 100644
--- a/src/main/python/apache/aurora/client/cli/cron.py
+++ b/src/main/python/apache/aurora/client/cli/cron.py
@@ -16,7 +16,13 @@
 
 from __future__ import print_function
 
-from apache.aurora.client.cli import EXIT_INVALID_PARAMETER, EXIT_OK, Noun, Verb
+from apache.aurora.client.cli import (
+    EXIT_COMMAND_FAILURE,
+    EXIT_INVALID_PARAMETER,
+    EXIT_OK,
+    Noun,
+    Verb
+)
 from apache.aurora.client.cli.context import AuroraCommandContext
 from apache.aurora.client.cli.options import (
     BIND_OPTION,
@@ -31,7 +37,7 @@ from apache.aurora.client.cli.options import (
 class Schedule(Verb):
   @property
   def name(self):
-    return 'schedule'
+    return "schedule"
 
   @property
   def help(self):
@@ -43,6 +49,11 @@ class Schedule(Verb):
   def execute(self, context):
     api = context.get_api(context.options.jobspec.cluster)
     config = context.get_job_config(context.options.jobspec, context.options.config_file)
+    if not config.raw().has_cron_schedule():
+      raise context.CommandError(
+          EXIT_COMMAND_FAILURE,
+          "Non-cron jobs may only be created with \"aurora job create\" command")
+
     resp = api.schedule_cron(config)
     context.check_and_log_response(resp,
         err_msg=("Error scheduling cron job %s:" % context.options.jobspec))
@@ -56,7 +67,7 @@ class Schedule(Verb):
 class Deschedule(Verb):
   @property
   def name(self):
-    return 'deschedule'
+    return "deschedule"
 
   @property
   def help(self):
@@ -70,13 +81,14 @@ class Deschedule(Verb):
     resp = api.deschedule_cron(context.options.jobspec)
     context.check_and_log_response(resp,
         err_msg=("Error descheduling cron job %s:" % context.options.jobspec))
+    context.print_out("Cron descheduling succeeded.")
     return EXIT_OK
 
 
 class Start(Verb):
   @property
   def name(self):
-    return 'start'
+    return "start"
 
   @property
   def help(self):
@@ -100,7 +112,7 @@ class Start(Verb):
 class Show(Verb):
   @property
   def name(self):
-    return 'show'
+    return "show"
 
   @property
   def help(self):
@@ -122,7 +134,7 @@ class Show(Verb):
           context.print_err("No cron entry found for job %s" % jobkey)
           return EXIT_INVALID_PARAMETER
         else:
-          context.print_out('%s\t %s' % (jobkey, job.cronSchedule))
+          context.print_out("%s\t %s" % (jobkey, job.cronSchedule))
           return EXIT_OK
     context.print_err("No cron entry found for job %s" % jobkey)
     return EXIT_INVALID_PARAMETER
@@ -131,7 +143,7 @@ class Show(Verb):
 class CronNoun(Noun):
   @property
   def name(self):
-    return 'cron'
+    return "cron"
 
   @property
   def help(self):

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/4d4b41aa/src/main/python/apache/aurora/client/cli/jobs.py
----------------------------------------------------------------------
diff --git a/src/main/python/apache/aurora/client/cli/jobs.py b/src/main/python/apache/aurora/client/cli/jobs.py
index 9aae558..987a736 100644
--- a/src/main/python/apache/aurora/client/cli/jobs.py
+++ b/src/main/python/apache/aurora/client/cli/jobs.py
@@ -65,7 +65,7 @@ from gen.apache.aurora.api.ttypes import ExecutorConfig, ResponseCode, ScheduleS
 
 def arg_type_jobkey(key):
   return AuroraCommandContext.parse_partial_jobkey(key)
-WILDCARD_JOBKEY_OPTION = CommandOption('jobspec', type=arg_type_jobkey,
+WILDCARD_JOBKEY_OPTION = CommandOption("jobspec", type=arg_type_jobkey,
         metavar="cluster[/role[/env[/name]]]",
         help="A jobkey, optionally containing wildcards")
 
@@ -102,7 +102,7 @@ class CreateJobCommand(Verb):
 
   @property
   def help(self):
-    return "Create a job using aurora"
+    return "Create a service or ad hoc job using aurora"
 
   CREATE_STATES = ("PENDING", "RUNNING", "FINISHED")
 
@@ -117,6 +117,11 @@ class CreateJobCommand(Verb):
 
   def execute(self, context):
     config = context.get_job_config(context.options.jobspec, context.options.config_file)
+    if config.raw().has_cron_schedule():
+      raise context.CommandError(
+          EXIT_COMMAND_FAILURE,
+          "Cron jobs may only be scheduled with \"aurora cron schedule\" command")
+
     api = context.get_api(config.cluster())
     resp = api.create_job(config)
     context.check_and_log_response(resp, err_code=EXIT_COMMAND_FAILURE,
@@ -461,12 +466,12 @@ class RestartCommand(Verb):
   def get_options(self):
     return [BATCH_OPTION, BIND_OPTION, BROWSER_OPTION, FORCE_OPTION, HEALTHCHECK_OPTION,
         JSON_READ_OPTION, WATCH_OPTION,
-        CommandOption('--max-per-instance-failures', type=int, default=0,
-             help='Maximum number of restarts per instance during restart. Increments total
'
-                  'failure count when this limit is exceeded.'),
-        CommandOption('--restart-threshold', type=int, default=60,
-             help='Maximum number of seconds before an instance must move into the RUNNING
state '
-                  'before considered a failure.'),
+        CommandOption("--max-per-instance-failures", type=int, default=0,
+             help="Maximum number of restarts per instance during restart. Increments total
"
+                  "failure count when this limit is exceeded."),
+        CommandOption("--restart-threshold", type=int, default=60,
+             help="Maximum number of seconds before an instance must move into the RUNNING
state "
+                  "before considered a failure."),
         CONFIG_OPTION,
         MAX_TOTAL_FAILURES_OPTION,
         STRICT_OPTION,
@@ -542,16 +547,16 @@ class StatusCommand(Verb):
           protocol_factory=TJSONProtocol.TSimpleJSONProtocolFactory()))
       # Now, clean it up: take all fields that are actually enums, and convert
       # their values to strings.
-      task['status'] = ScheduleStatus._VALUES_TO_NAMES[task['status']]
-      events = sorted(task['taskEvents'], key=lambda event: event['timestamp'])
+      task["status"] = ScheduleStatus._VALUES_TO_NAMES[task["status"]]
+      events = sorted(task["taskEvents"], key=lambda event: event["timestamp"])
       for event in events:
-        event['status'] = ScheduleStatus._VALUES_TO_NAMES[event['status']]
+        event["status"] = ScheduleStatus._VALUES_TO_NAMES[event["status"]]
       # convert boolean fields to boolean value names.
-      assigned = task['assignedTask']
-      task_config = assigned['task']
-      task_config['isService'] = (task_config['isService'] != 0)
-      if 'production' in task_config:
-        task_config['production'] = (task_config['production'] != 0)
+      assigned = task["assignedTask"]
+      task_config = assigned["task"]
+      task_config["isService"] = (task_config["isService"] != 0)
+      if "production" in task_config:
+        task_config["production"] = (task_config["production"] != 0)
       return task
 
     return {"job": str(jobkey),
@@ -589,7 +594,7 @@ class StatusCommand(Verb):
         task_strings.append("\t  metadata:")
         for md in assigned_task.task.metadata:
           task_strings.append("\t\t  (key: '%s', value: '%s')" % (md.key, md.value))
-      task_strings.append('')
+      task_strings.append("")
       return "\n".join(task_strings)
 
     result = ["Active tasks (%s):\n" % len(active_tasks)]
@@ -622,9 +627,9 @@ class StatusCommand(Verb):
     if result == []:
       return None
     if context.options.write_json:
-      return json.dumps(result, indent=2, separators=[',', ': '], sort_keys=False)
+      return json.dumps(result, indent=2, separators=[",", ": "], sort_keys=False)
     else:
-      return ''.join(result)
+      return "".join(result)
 
   def _print_jobs_not_found(self, context):
     if context.options.write_json:
@@ -657,7 +662,7 @@ class StatusCommand(Verb):
 class UpdateCommand(Verb):
   @property
   def name(self):
-    return 'update'
+    return "update"
 
   def get_options(self):
     return [FORCE_OPTION, BIND_OPTION, JSON_READ_OPTION, HEALTHCHECK_OPTION,

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/4d4b41aa/src/test/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterfaceTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterfaceTest.java
b/src/test/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterfaceTest.java
index 5c9ea6c..871ddbc 100644
--- a/src/test/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterfaceTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/thrift/SchedulerThriftInterfaceTest.java
@@ -165,6 +165,8 @@ import static org.apache.aurora.scheduler.thrift.SchedulerThriftInterface.MAX_TA
 import static org.apache.aurora.scheduler.thrift.SchedulerThriftInterface.MAX_TASK_ID_LENGTH;
 import static org.apache.aurora.scheduler.thrift.SchedulerThriftInterface.NOOP_JOB_UPDATE_MESSAGE;
 import static org.apache.aurora.scheduler.thrift.SchedulerThriftInterface.killedByMessage;
+import static org.apache.aurora.scheduler.thrift.SchedulerThriftInterface.noCronScheduleMessage;
+import static org.apache.aurora.scheduler.thrift.SchedulerThriftInterface.notScheduledCronMessage;
 import static org.apache.aurora.scheduler.thrift.SchedulerThriftInterface.restartedByMessage;
 import static org.apache.aurora.scheduler.thrift.SchedulerThriftInterface.transitionMessage;
 import static org.easymock.EasyMock.anyInt;
@@ -1200,7 +1202,10 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest {
     expectAuth(ROLE, true);
     lockManager.validateIfLocked(LOCK_KEY, Optional.<ILock>absent());
     control.replay();
-    assertResponse(INVALID_REQUEST, thrift.scheduleCronJob(makeJob(), DEFAULT_LOCK, SESSION));
+
+    assertEquals(
+        invalidResponse(noCronScheduleMessage(JOB_KEY)),
+        thrift.scheduleCronJob(makeJob(), DEFAULT_LOCK, SESSION));
   }
 
   @Test
@@ -1246,13 +1251,15 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest {
   }
 
   @Test
-  public void testDescheduleCronJobWithError() throws Exception {
+  public void testDescheduleNotACron() throws Exception {
     expectAuth(ROLE, true);
     lockManager.validateIfLocked(LOCK_KEY, Optional.<ILock>absent());
     expect(cronJobManager.deleteJob(JOB_KEY)).andReturn(false);
     control.replay();
-    assertResponse(INVALID_REQUEST,
-        thrift.descheduleCronJob(CRON_JOB.getKey(), DEFAULT_LOCK, SESSION));
+
+    assertEquals(
+        invalidResponse(notScheduledCronMessage(JOB_KEY)),
+        thrift.descheduleCronJob(JOB_KEY.newBuilder(), DEFAULT_LOCK, SESSION));
   }
 
   @Test
@@ -1573,6 +1580,15 @@ public class SchedulerThriftInterfaceTest extends EasyMockTest {
         .setResult(result);
   }
 
+  private Response invalidResponse(String message) {
+    return Util.emptyResponse()
+        .setResponseCode(INVALID_REQUEST)
+        .setDEPRECATEDversion(API_VERSION)
+        .setServerInfo(SERVER_INFO)
+        .setMessageDEPRECATED(message)
+        .setDetails(ImmutableList.of(new ResponseDetail(message)));
+  }
+
   @Test
   public void testGetJobs() throws Exception {
     TaskConfig ownedCronJobTask = nonProductionTask()

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/4d4b41aa/src/test/python/apache/aurora/client/cli/test_create.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_create.py b/src/test/python/apache/aurora/client/cli/test_create.py
index 26a10d4..9aaf82a 100644
--- a/src/test/python/apache/aurora/client/cli/test_create.py
+++ b/src/test/python/apache/aurora/client/cli/test_create.py
@@ -65,6 +65,9 @@ class TestCreateJobCommand(unittest.TestCase):
     fake_context.set_options(mock_options)
 
     mock_config = create_autospec(spec=AuroraConfig, spec_set=True, instance=True)
+    mock_job_config = Mock()
+    mock_job_config.has_cron_schedule.return_value = False
+    mock_config.raw.return_value = mock_job_config
     fake_context.get_job_config = Mock(return_value=mock_config)
     mock_api = fake_context.get_api("test")
 
@@ -420,3 +423,15 @@ class TestClientCreateCommand(AuroraClientCommandTest):
       assert mock_context.get_err() == [
           "TypeCheck(FAILED): MesosJob[update_config] failed: "
           "UpdateConfig[batch_size] failed: u'{{TEST_BATCH}}' not an integer"]
+
+  def test_create_cron_job_fails(self):
+    """Test a cron job is not accepted."""
+    mock_context = FakeAuroraCommandContext()
+    with patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context):
+      with temporary_file() as fp:
+        fp.write(self.get_valid_cron_config())
+        fp.flush()
+        cmd = AuroraCommandLine()
+        result = cmd.execute(['job', 'create', '--wait-until=RUNNING',
+            'west/bozo/test/hello', fp.name])
+        assert result == EXIT_COMMAND_FAILURE

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/4d4b41aa/src/test/python/apache/aurora/client/cli/test_cron.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_cron.py b/src/test/python/apache/aurora/client/cli/test_cron.py
index 9c1f0be..c748212 100644
--- a/src/test/python/apache/aurora/client/cli/test_cron.py
+++ b/src/test/python/apache/aurora/client/cli/test_cron.py
@@ -19,7 +19,12 @@ import contextlib
 from mock import create_autospec, patch
 from twitter.common.contextutil import temporary_file
 
-from apache.aurora.client.cli import EXIT_API_ERROR, EXIT_INVALID_CONFIGURATION, EXIT_OK
+from apache.aurora.client.cli import (
+    EXIT_API_ERROR,
+    EXIT_COMMAND_FAILURE,
+    EXIT_INVALID_CONFIGURATION,
+    EXIT_OK
+)
 from apache.aurora.client.cli.client import AuroraCommandLine
 from apache.aurora.common.aurora_job_key import AuroraJobKey
 from apache.aurora.config import AuroraConfig
@@ -41,7 +46,7 @@ class TestCronNoun(AuroraClientCommandTest):
       api = mock_context.get_api('west')
       api.schedule_cron.return_value = self.create_simple_success_response()
       with temporary_file() as fp:
-        fp.write(self.get_valid_config())
+        fp.write(self.get_valid_cron_config())
         fp.flush()
         cmd = AuroraCommandLine()
         cmd.execute(['cron', 'schedule', key.to_path(), fp.name])
@@ -60,7 +65,7 @@ class TestCronNoun(AuroraClientCommandTest):
       api = mock_context.get_api('west')
       api.schedule_cron.return_value = self.create_error_response()
       with temporary_file() as fp:
-        fp.write(self.get_valid_config())
+        fp.write(self.get_valid_cron_config())
         fp.flush()
         cmd = AuroraCommandLine()
         result = cmd.execute(['cron', 'schedule', 'west/bozo/test/hello', fp.name])
@@ -70,11 +75,21 @@ class TestCronNoun(AuroraClientCommandTest):
       # Check that create_job was called exactly once, with an AuroraConfig parameter.
       assert api.schedule_cron.call_count == 1
 
+  def test_schedule_failed_non_cron(self):
+    mock_context = FakeAuroraCommandContext()
+    with patch('apache.aurora.client.cli.cron.CronNoun.create_context', return_value=mock_context):
+      with temporary_file() as fp:
+        fp.write(self.get_valid_config())
+        fp.flush()
+        cmd = AuroraCommandLine()
+        result = cmd.execute(['cron', 'schedule', 'west/bozo/test/hello', fp.name])
+        assert result == EXIT_COMMAND_FAILURE
+
   def test_schedule_cron_failed_invalid_config(self):
     mock_context = FakeAuroraCommandContext()
     with patch('apache.aurora.client.cli.cron.CronNoun.create_context', return_value=mock_context):
       with temporary_file() as fp:
-        fp.write(self.get_invalid_config('invalid_clause=oops'))
+        fp.write(self.get_invalid_cron_config('invalid_clause=oops'))
         fp.flush()
         cmd = AuroraCommandLine()
         result = cmd.execute(['cron', 'schedule', 'west/bozo/test/hello', fp.name])
@@ -93,7 +108,7 @@ class TestCronNoun(AuroraClientCommandTest):
         patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
       mock_scheduler_proxy.scheduleCronJob.return_value = self.create_simple_success_response()
       with temporary_file() as fp:
-        fp.write(self.get_valid_config())
+        fp.write(self.get_valid_cron_config())
         fp.flush()
         cmd = AuroraCommandLine()
         result = cmd.execute(['cron', 'schedule', 'west/bozo/test/hello', fp.name])

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/4d4b41aa/src/test/python/apache/aurora/client/cli/util.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/util.py b/src/test/python/apache/aurora/client/cli/util.py
index a89211a..0ec74e6 100644
--- a/src/test/python/apache/aurora/client/cli/util.py
+++ b/src/test/python/apache/aurora/client/cli/util.py
@@ -248,6 +248,19 @@ HELLO_WORLD = Job(
 jobs = [HELLO_WORLD]
 """
 
+  CRON_CONFIG_BASE = """
+HELLO_WORLD = Job(
+  name = '%(job)s',
+  role = '%(role)s',
+  cluster = '%(cluster)s',
+  environment = '%(env)s',
+  cron_schedule = '*/5 * * * *',
+  %(inner)s
+  task = SimpleTask('test', 'echo test')
+)
+jobs = [HELLO_WORLD]
+"""
+
   UNBOUND_CONFIG = textwrap.dedent("""\
       HELLO_WORLD = Job(
         name = '%(job)s',
@@ -289,9 +302,9 @@ jobs = [HELLO_WORLD]
       auth_mechanism='UNAUTHENTICATED')])
 
   @classmethod
-  def get_test_config(cls, cluster, role, env, job, filler=''):
+  def get_test_config(cls, base, cluster, role, env, job, filler=''):
     """Create a config from the template"""
-    return cls.CONFIG_BASE % {'job': job, 'role': role, 'env': env, 'cluster': cluster,
+    return base % {'job': job, 'role': role, 'env': env, 'cluster': cluster,
         'inner': filler}
 
   @classmethod
@@ -302,11 +315,40 @@ jobs = [HELLO_WORLD]
 
   @classmethod
   def get_valid_config(cls):
-    return cls.get_test_config(cls.TEST_CLUSTER, cls.TEST_ROLE, cls.TEST_ENV, cls.TEST_JOB)
+    return cls.get_test_config(
+        cls.CONFIG_BASE,
+        cls.TEST_CLUSTER,
+        cls.TEST_ROLE,
+        cls.TEST_ENV,
+        cls.TEST_JOB)
+
+  @classmethod
+  def get_valid_cron_config(cls):
+    return cls.get_test_config(
+        cls.CRON_CONFIG_BASE,
+        cls.TEST_CLUSTER,
+        cls.TEST_ROLE,
+        cls.TEST_ENV,
+        cls.TEST_JOB)
 
   @classmethod
   def get_invalid_config(cls, bad_clause):
-    return cls.get_test_config(cls.TEST_CLUSTER, cls.TEST_ROLE, cls.TEST_ENV, cls.TEST_JOB,
+    return cls.get_test_config(
+        cls.CONFIG_BASE,
+        cls.TEST_CLUSTER,
+        cls.TEST_ROLE,
+        cls.TEST_ENV,
+        cls.TEST_JOB,
+        bad_clause)
+
+  @classmethod
+  def get_invalid_cron_config(cls, bad_clause):
+    return cls.get_test_config(
+        cls.CRON_CONFIG_BASE,
+        cls.TEST_CLUSTER,
+        cls.TEST_ROLE,
+        cls.TEST_ENV,
+        cls.TEST_JOB,
         bad_clause)
 
 


Mime
View raw message