Repository: aurora Updated Branches: refs/heads/master 34be63158 -> f2acf53ff
http://git-wip-us.apache.org/repos/asf/aurora/blob/f2acf53f/src/test/python/apache/aurora/client/cli/test_kill.py ---------------------------------------------------------------------- diff --git a/src/test/python/apache/aurora/client/cli/test_kill.py b/src/test/python/apache/aurora/client/cli/test_kill.py index 0e859dc..bb78ee2 100644 --- a/src/test/python/apache/aurora/client/cli/test_kill.py +++ b/src/test/python/apache/aurora/client/cli/test_kill.py @@ -59,7 +59,8 @@ class TestKillCommand(AuroraClientCommandTest): fake_context = FakeAuroraCommandContext() fake_context.set_options(mock_options) - + fake_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) mock_api = fake_context.get_api('test') mock_api.kill_job.return_value = AuroraClientCommandTest.create_blank_response( ResponseCode.JOB_UPDATING_ERROR, "Error.") @@ -86,6 +87,8 @@ class TestKillCommand(AuroraClientCommandTest): fake_context.set_options(mock_options) fake_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) + fake_context.add_expected_query_result( AuroraClientCommandTest.create_query_call_result( AuroraClientCommandTest.create_scheduled_task(1, ScheduleStatus.RUNNING))) @@ -115,6 +118,8 @@ class TestKillCommand(AuroraClientCommandTest): fake_context = FakeAuroraCommandContext() fake_context.set_options(mock_options) + fake_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) fake_context.add_expected_query_result(AuroraClientCommandTest.create_empty_task_result()) with pytest.raises(Context.CommandError) as e: @@ -131,6 +136,8 @@ class TestKillCommand(AuroraClientCommandTest): fake_context = FakeAuroraCommandContext() fake_context.set_options(mock_options) + fake_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) fake_context.add_expected_query_result(AuroraClientCommandTest.create_empty_task_result()) command.execute(fake_context) @@ -147,6 +154,8 @@ class TestKillCommand(AuroraClientCommandTest): fake_context = FakeAuroraCommandContext() fake_context.set_options(mock_options) + fake_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) fake_context.add_expected_query_result(AuroraClientCommandTest.create_empty_task_result()) command.execute(fake_context) @@ -170,6 +179,8 @@ class TestKillCommand(AuroraClientCommandTest): fake_context.add_config(config) mock_api = fake_context.get_api('test') + fake_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) fake_context.add_expected_query_result(AuroraClientCommandTest.create_empty_task_result()) mock_api.kill_job.return_value = self.create_simple_success_response() @@ -194,6 +205,8 @@ class TestKillCommand(AuroraClientCommandTest): fake_context.add_config(config) fake_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) + fake_context.add_expected_query_result( AuroraClientCommandTest.create_query_call_result( AuroraClientCommandTest.create_scheduled_task(1, ScheduleStatus.RUNNING))) @@ -222,6 +235,8 @@ class TestKillAllCommand(AuroraClientCommandTest): fake_context.add_config(config) mock_api = fake_context.get_api('test') + fake_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) fake_context.add_expected_query_result(AuroraClientCommandTest.create_empty_task_result()) mock_api.kill_job.return_value = self.create_simple_success_response() @@ -272,8 +287,9 @@ class TestClientKillCommand(AuroraClientCommandTest): assert api.kill_job.mock_calls == [call(cls.TEST_JOBKEY, None, config=None, message=None)] @classmethod - def assert_query(cls, fake_api): - calls = [call(TaskQuery(jobKeys=[cls.TEST_JOBKEY.to_thrift()], statuses=ACTIVE_STATES))] + def assert_query(cls, fake_api, times=1): + calls = [call(TaskQuery(jobKeys=[cls.TEST_JOBKEY.to_thrift()], statuses=ACTIVE_STATES)) + for _ in range(times)] assert fake_api.query_no_configs.mock_calls == calls def test_killall_job(self): @@ -321,6 +337,8 @@ class TestClientKillCommand(AuroraClientCommandTest): patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context), patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor)) as (_, m): api = mock_context.get_api('west') + mock_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) api.kill_job.return_value = self.create_simple_success_response() cmd = AuroraCommandLine() cmd.execute(['job', 'kill', '--no-batching', self.get_instance_spec('0,2,4-6')]) @@ -328,6 +346,7 @@ class TestClientKillCommand(AuroraClientCommandTest): instances = [0, 2, 4, 5, 6] self.assert_kill_calls(api, instances=instances, message=None) self.assert_wait_calls(mock_monitor, m.terminal, instances=instances) + self.assert_query(api) def test_kill_job_with_invalid_instances_strict(self): """Test kill client-side API logic.""" @@ -350,12 +369,15 @@ class TestClientKillCommand(AuroraClientCommandTest): patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context), patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor)) as (_, m): api = mock_context.get_api('west') + mock_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) api.kill_job.return_value = self.create_simple_success_response() cmd = AuroraCommandLine() cmd.execute(['job', 'kill', '--no-batching', self.get_instance_spec('0,2,4-6,11-13')]) instances = [0, 2, 4, 5, 6, 11, 12, 13] self.assert_kill_calls(api, instances=instances, message=None) self.assert_wait_calls(mock_monitor, m.terminal, instances=instances) + self.assert_query(api) def test_kill_job_with_instances_batched(self): """Test kill client-side API logic.""" @@ -366,7 +388,9 @@ class TestClientKillCommand(AuroraClientCommandTest): patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor)) as (_, m): api = mock_context.get_api('west') mock_context.add_expected_query_result( - self.create_query_call_result(), job_key=self.TEST_JOBKEY) + self.create_query_call_result(), job_key=self.TEST_JOBKEY) + mock_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) api.kill_job.return_value = self.create_simple_success_response() cmd = AuroraCommandLine() @@ -374,7 +398,7 @@ class TestClientKillCommand(AuroraClientCommandTest): self.assert_kill_calls(api, instance_range=range(7)) self.assert_wait_calls(mock_monitor, m.terminal, instance_range=range(7)) - self.assert_query(api) + self.assert_query(api, times=2) def test_kill_job_with_instances_batched_maxerrors(self): """Test kill client-side API logic.""" @@ -385,7 +409,9 @@ class TestClientKillCommand(AuroraClientCommandTest): patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor)): api = mock_context.get_api('west') mock_context.add_expected_query_result( - self.create_query_call_result(), job_key=self.TEST_JOBKEY) + self.create_query_call_result(), job_key=self.TEST_JOBKEY) + mock_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) api.kill_job.return_value = self.create_simple_success_response() cmd = AuroraCommandLine() @@ -393,7 +419,7 @@ class TestClientKillCommand(AuroraClientCommandTest): # We should have aborted after the second batch. self.assert_kill_calls(api, instance_range=range(2), message=None) - self.assert_query(api) + self.assert_query(api, times=2) def test_kill_job_with_empty_instances_batched(self): """Test kill client-side API logic.""" @@ -401,6 +427,8 @@ class TestClientKillCommand(AuroraClientCommandTest): with contextlib.nested( patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context)): api = mock_context.get_api('west') + mock_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) # set up an empty instance list in the getTasksWithoutConfigs response status_response = self.create_simple_success_response() status_response.result = Result(scheduleStatusResult=ScheduleStatusResult(tasks=[])) @@ -410,6 +438,7 @@ class TestClientKillCommand(AuroraClientCommandTest): cmd.execute(['job', 'kill', self.get_instance_spec('0,2,4-13')]) assert api.kill_job.call_count == 0 + self.assert_query(api, times=2) def test_killall_job_output(self): """Test kill output.""" @@ -433,6 +462,8 @@ class TestClientKillCommand(AuroraClientCommandTest): patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context), patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=self.get_monitor_mock())): api = mock_context.get_api('west') + mock_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) mock_context.add_expected_query_result(self.create_query_call_result()) api.kill_job.return_value = self.create_simple_success_response() cmd = AuroraCommandLine() @@ -441,6 +472,7 @@ class TestClientKillCommand(AuroraClientCommandTest): assert mock_context.get_out() == ['Successfully killed instances [0, 2, 4, 5, 6]', 'Job kill succeeded'] assert mock_context.get_err() == [] + self.assert_query(api, times=2) def test_kill_job_with_instances_batched_maxerrors_output(self): """Test kill client-side API logic.""" @@ -450,6 +482,8 @@ class TestClientKillCommand(AuroraClientCommandTest): patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context), patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor)): api = mock_context.get_api('west') + mock_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) mock_context.add_expected_query_result(self.create_query_call_result()) api.kill_job.return_value = self.create_simple_success_response() cmd = AuroraCommandLine() @@ -461,6 +495,7 @@ class TestClientKillCommand(AuroraClientCommandTest): 'Instances [0, 2, 4, 5, 6] were not killed in time', 'Instances [7, 8, 9, 10, 11] were not killed in time', 'Exceeded maximum number of errors while killing instances'] + self.assert_query(api, times=2) def test_kill_job_with_message(self): """Test kill client-side API logic.""" @@ -470,6 +505,8 @@ class TestClientKillCommand(AuroraClientCommandTest): patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context), patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor)) as (_, m): api = mock_context.get_api('west') + mock_context.add_expected_query_result( + self.create_query_call_result(), job_key=self.TEST_JOBKEY) api.kill_job.return_value = self.create_simple_success_response() cmd = AuroraCommandLine() message = 'Test message' @@ -477,3 +514,4 @@ class TestClientKillCommand(AuroraClientCommandTest): instances = [0] self.assert_kill_calls(api, instances=instances, message=message) + self.assert_query(api) http://git-wip-us.apache.org/repos/asf/aurora/blob/f2acf53f/src/test/sh/org/apache/aurora/e2e/http_example.py ---------------------------------------------------------------------- diff --git a/src/test/sh/org/apache/aurora/e2e/http_example.py b/src/test/sh/org/apache/aurora/e2e/http_example.py index ba7d114..140cc75 100644 --- a/src/test/sh/org/apache/aurora/e2e/http_example.py +++ b/src/test/sh/org/apache/aurora/e2e/http_example.py @@ -14,7 +14,6 @@ from __future__ import print_function from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer -from SocketServer import ThreadingMixIn from sys import argv from threading import Thread @@ -41,6 +40,7 @@ def start_server(port, handler_class): print('Listening on port %s' % port) server.serve_forever() + request_thread = Thread(target=start_server, args=[int(argv[1]), RequestHandler]) health_thread = Thread(target=start_server, args=[int(argv[2]), HealthHandler]) http://git-wip-us.apache.org/repos/asf/aurora/blob/f2acf53f/src/test/sh/org/apache/aurora/e2e/partition_aware.aurora ---------------------------------------------------------------------- diff --git a/src/test/sh/org/apache/aurora/e2e/partition_aware.aurora b/src/test/sh/org/apache/aurora/e2e/partition_aware.aurora index 7ea9fad..98732e4 100644 --- a/src/test/sh/org/apache/aurora/e2e/partition_aware.aurora +++ b/src/test/sh/org/apache/aurora/e2e/partition_aware.aurora @@ -1,3 +1,17 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + # run the script hello_world = Process( name = 'hello_world', http://git-wip-us.apache.org/repos/asf/aurora/blob/f2acf53f/src/test/sh/org/apache/aurora/e2e/sla_coordinator.py ---------------------------------------------------------------------- diff --git a/src/test/sh/org/apache/aurora/e2e/sla_coordinator.py b/src/test/sh/org/apache/aurora/e2e/sla_coordinator.py new file mode 100644 index 0000000..24aa8f5 --- /dev/null +++ b/src/test/sh/org/apache/aurora/e2e/sla_coordinator.py @@ -0,0 +1,60 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import print_function + +from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer +from threading import Thread +from urlparse import urlparse, parse_qs + +import json +import sys + + +class RequestHandler(BaseHTTPRequestHandler): + def do_POST(self): + task = parse_qs(urlparse(self.path).query)['task'][0] + body = self.rfile.read(int(self.headers.getheader('content-length', 0))) + + # Only allow draining instance-0 + allow = True if task == 'devcluster/vagrant/test/coordinator/0' else False + + self.send_response(200) + self.send_header('Content-Type', 'application/json') + self.end_headers() + self.wfile.write('{"drain":%s}' % allow) + + print('Request received for {}'.format(task)) + print(json.dumps(json.loads(body), indent=2, sort_keys=True)) + print('Responded: {}'.format(allow)) + sys.stdout.flush() + + +def start_server(instance, port, handler_class): + # This service will act as its own SLA Coordinator. + # We need a static port for the coordinator service so the scheduler can communicate to it when + # checking SLA. We cannot have 2 tasks binding to the same port so instance-1 will bind to 8080 + # as instance-0 is the one that will be acked for draining. instance-0 will bind to a random port. + if instance != 1: + port = 0 + + server = HTTPServer(('', port), handler_class) + print('Listening on port %s' % port) + sys.stdout.flush() + server.serve_forever() + + +thread = Thread(target=start_server, args=[int(sys.argv[1]), 8080, RequestHandler]) + +thread.start() +thread.join() http://git-wip-us.apache.org/repos/asf/aurora/blob/f2acf53f/src/test/sh/org/apache/aurora/e2e/sla_policy.aurora ---------------------------------------------------------------------- diff --git a/src/test/sh/org/apache/aurora/e2e/sla_policy.aurora b/src/test/sh/org/apache/aurora/e2e/sla_policy.aurora new file mode 100644 index 0000000..d819778 --- /dev/null +++ b/src/test/sh/org/apache/aurora/e2e/sla_policy.aurora @@ -0,0 +1,61 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +hello = Process( + name = 'hello', + cmdline = """ + while true; do + echo hello world + sleep 10 + done + """) + +copy_coordinator = Process( + name = 'copy_coordinator', + cmdline = 'cp /vagrant/src/test/sh/org/apache/aurora/e2e/sla_coordinator.py .' +) + +run_coordinator = Process( + name = 'run_coordinator', + cmdline = 'python sla_coordinator.py {{mesos.instance}}') + +task = SequentialTask( + processes = [hello], + resources = Resources(cpu = 0.1, ram = 1*MB, disk = 8*MB)) + +coordinator_task = SequentialTask( + processes = [copy_coordinator, run_coordinator], + resources = Resources(cpu = 0.1, ram = 1*MB, disk = 8*MB)) + +service = Service( + task = task, + tier = 'preferred', + instances = 2, + cluster = 'devcluster', + role = 'vagrant', + environment = 'test') + +coordinator_service = Service( + task = coordinator_task, + tier = 'preferred', + instances = 2, + cluster = 'devcluster', + role = 'vagrant', + environment = 'test') + +jobs = [ + service(name = 'count', sla_policy=CountSlaPolicy(count=1, duration_secs=60)), + service(name = 'percentage', sla_policy=PercentageSlaPolicy(percentage=50, duration_secs=60)), + coordinator_service(name = 'coordinator', sla_policy=CoordinatorSlaPolicy(coordinator_url='http://localhost:8080')), +] http://git-wip-us.apache.org/repos/asf/aurora/blob/f2acf53f/src/test/sh/org/apache/aurora/e2e/test_end_to_end.sh ---------------------------------------------------------------------- diff --git a/src/test/sh/org/apache/aurora/e2e/test_end_to_end.sh b/src/test/sh/org/apache/aurora/e2e/test_end_to_end.sh index 888efe4..24f4448 100755 --- a/src/test/sh/org/apache/aurora/e2e/test_end_to_end.sh +++ b/src/test/sh/org/apache/aurora/e2e/test_end_to_end.sh @@ -33,11 +33,16 @@ _curl() { curl --silent --fail --retry 4 --retry-delay 10 "$@" ; } tear_down() { set +x # Disable command echo, as this makes it more difficult see which command failed. - for job in http_example http_example_watch_secs http_example_revocable http_example_docker http_example_unified_appc http_example_unified_docker; do - aurora update abort devcluster/vagrant/test/$job >/dev/null 2>&1 || true - aurora job killall --no-batching devcluster/vagrant/test/$job >/dev/null 2>&1 + local _jobs=$(aurora job list $TEST_CLUSTER/$TEST_ROLE| grep $TEST_ROLE) + + for job in ${_jobs[@]}; do + aurora update abort $job >/dev/null 2>&1 || true + aurora job killall --no-batching $job >/dev/null 2>&1 done + aurora_admin set_quota $TEST_CLUSTER $TEST_ROLE 0 0m 0m + aurora_admin host_activate --hosts=$TEST_SLAVE_IP $TEST_CLUSTER + sudo mv /etc/aurora/clusters.json.old /etc/aurora/clusters.json >/dev/null 2>&1 || true } @@ -241,12 +246,50 @@ wait_until_task_status() { _success=1 break else - sleep 1 + sleep 20 + fi + done + + if [[ "$_success" -ne "1" ]]; then + echo "Task did not transition to $_expected_state within timeout." + exit 1 + fi +} + +assert_host_status() { + local _host=$1 _cluster=$2 _expected_state=$3 + + local _state=$(aurora_admin host_status --hosts=$_host $_cluster 2>&1 | tail -n1 | awk -F' ' '{print $6}') + + if [[ $_state != $_expected_state ]]; then + echo "Expected host $_host to be in state $_expected_state, but found $_state" + exit 1 + fi +} + +wait_until_task_counts() { + # Poll the job, waiting for it to enter the target number of task counts + local _jobkey=$1 _expected_running=$2 _expected_pending=$3 + local _num_running=0 + local _num_pending=0 + local _success=0 + + for i in $(seq 1 120); do + # || is so that we don't return an EXIT so that `trap collect_result` doesn't get triggered. + _num_running=$(aurora job status $_jobkey --write-json | jq -r ".[0].active[].status" | grep "RUNNING" | wc -l) || echo $? + _num_pending=$(aurora job status $_jobkey --write-json | jq -r ".[0].active[].status" | grep "PENDING" | wc -l) || echo $? + + if [[ $_num_running == $_expected_running ]] && [[ $_num_pending == $_expected_pending ]]; then + _success=1 + break + else + echo "Waiting for job $_jobkey to have $_expected_running RUNNING and $_expected_pending PENDING tasks." + sleep 20 fi done if [[ "$_success" -ne "1" ]]; then - echo "Task did not transition to $_expected_state within two minutes." + echo "Job $_jobkey did not have $_expected_running RUNNING tasks and $_expected_pending PENDING tasks within timeout." exit 1 fi } @@ -341,6 +384,73 @@ test_partition_awareness() { aurora job killall $_delay_jobkey } +run_sla_aware_maintenance() { + local _config=$1 + local _cluster=$2 + local _jobkey=$3 + + aurora job create $_jobkey $_config --wait-until RUNNING + + # assert the number of tasks, the job should have 2 RUNNING tasks + wait_until_task_counts $_jobkey 2 0 + + # check that the host starts with no maintenance mode + assert_host_status $TEST_SLAVE_IP $_cluster "NONE" + + # trigger sla aware drain with default timeout of 2hr + # so, only allowed number (1 each) of tasks should drain for each job + aurora_admin sla_host_drain --hosts=$TEST_SLAVE_IP $_cluster + + # force a scheduler restart and make sure that the maintenance request is still satisfied + sudo systemctl restart aurora-scheduler + + # host must have maintenance mode set + assert_host_status $TEST_SLAVE_IP $_cluster "DRAINING" + + # tasks get drained as allowed by the sla policy + wait_until_task_counts $_jobkey 1 1 + + # for coordinator sla check specific task states + if [[ $_jobkey == $TEST_JOB_COORDINATOR_SLA ]]; then + assert_task_status $_jobkey "0" PENDING + assert_task_status $_jobkey "1" RUNNING + fi + + # host must have maintenance mode set and should be waiting in DRAINING + assert_host_status $TEST_SLAVE_IP $_cluster "DRAINING" + + # force sla aware drain with zero timeout + aurora_admin sla_host_drain --force_drain_timeout=0s --hosts=$TEST_SLAVE_IP $_cluster + + # tasks get drained as allowed by the sla policy + wait_until_task_counts $_jobkey 0 2 + + # activate host again + aurora_admin host_activate --hosts=$TEST_SLAVE_IP $_cluster + + # assert the number of tasks the job should have 2 RUNNING tasks + wait_until_task_counts $_jobkey 2 0 + + # clean up + aurora job killall $_jobkey +} + +test_sla_aware_maintenance() { + local _config=$1 + local _cluster=$2 + local _role=$3 + local _count_jobkey=$4 + local _percentage_jobkey=$5 + local _coordinator_jobkey=$6 + + # add quota for each job (addl. for executor overhead) since only preferred jobs get sla policy + aurora_admin increase_quota $_cluster $_role 1.0 10m 50m + + run_sla_aware_maintenance $_config $_cluster $_count_jobkey + run_sla_aware_maintenance $_config $_cluster $_percentage_jobkey + run_sla_aware_maintenance $_config $_cluster $_coordinator_jobkey +} + test_announce() { local _role=$1 _env=$2 _job=$3 @@ -744,6 +854,10 @@ TEST_PARTITION_AWARENESS_CONFIG_FILE=$TEST_ROOT/partition_aware.aurora TEST_JOB_PA_DEFAULT=$TEST_CLUSTER/$TEST_ROLE/$TEST_ENV/partition_aware_default TEST_JOB_PA_DISABLED=$TEST_CLUSTER/$TEST_ROLE/$TEST_ENV/partition_aware_disabled TEST_JOB_PA_DELAY=$TEST_CLUSTER/$TEST_ROLE/$TEST_ENV/partition_aware_delay +TEST_SLA_POLICY_CONFIG_FILE=$TEST_ROOT/sla_policy.aurora +TEST_JOB_COUNT_SLA=$TEST_CLUSTER/$TEST_ROLE/$TEST_ENV/count +TEST_JOB_PERCENTAGE_SLA=$TEST_CLUSTER/$TEST_ROLE/$TEST_ENV/percentage +TEST_JOB_COORDINATOR_SLA=$TEST_CLUSTER/$TEST_ROLE/$TEST_ENV/coordinator BASE_ARGS=( $TEST_CLUSTER @@ -792,6 +906,15 @@ TEST_PARTITION_AWARENESS_ARGS=( $TEST_JOB_PA_DELAY ) +TEST_SLA_AWARE_MAINTENANCE_ARGS=( + $TEST_SLA_POLICY_CONFIG_FILE + $TEST_CLUSTER + $TEST_ROLE + $TEST_JOB_COUNT_SLA + $TEST_JOB_PERCENTAGE_SLA + $TEST_JOB_COORDINATOR_SLA +) + TEST_JOB_KILL_MESSAGE_ARGS=("${TEST_JOB_ARGS[@]}" "--message='Test message'") trap collect_result EXIT @@ -800,6 +923,8 @@ aurorabuild all setup_ssh setup_docker_registry +test_sla_aware_maintenance "${TEST_SLA_AWARE_MAINTENANCE_ARGS[@]}" + test_partition_awareness "${TEST_PARTITION_AWARENESS_ARGS[@]}" test_version http://git-wip-us.apache.org/repos/asf/aurora/blob/f2acf53f/ui/src/main/js/components/TaskConfigSummary.js ---------------------------------------------------------------------- diff --git a/ui/src/main/js/components/TaskConfigSummary.js b/ui/src/main/js/components/TaskConfigSummary.js index 64880f4..f03d44d 100644 --- a/ui/src/main/js/components/TaskConfigSummary.js +++ b/ui/src/main/js/components/TaskConfigSummary.js @@ -70,6 +70,46 @@ function PartitionPolicy({ config }) { <td>{config.partitionPolicy.delaySecs}</td> </tr>]; } + +function SlaPolicy({ config }) { + if (isNully(config.slaPolicy)) { + return null; + } + + if (!isNully(config.slaPolicy.countSlaPolicy)) { + return [<tr> + <th rowSpan='2'>Count SLA Policy</th> + <td>count</td> + <td>{config.slaPolicy.countSlaPolicy.count}</td> + </tr>, + <tr> + <td>duration secs</td> + <td>{config.slaPolicy.countSlaPolicy.durationSecs}</td> + </tr>]; + } else if (!isNully(config.slaPolicy.percentageSlaPolicy)) { + return [<tr> + <th rowSpan='2'>Percentage SLA Policy</th> + <td>precentage</td> + <td>{config.slaPolicy.percentageSlaPolicy.percentage + '%'}</td> + </tr>, + <tr> + <td>duration secs</td> + <td>{config.slaPolicy.percentageSlaPolicy.durationSecs}</td> + </tr>]; + } else if (!isNully(config.slaPolicy.coordinatorSlaPolicy)) { + return [<tr> + <th rowSpan='4'>Coordinator SLA Policy</th> + <td>coordinator url</td> + <td>{config.slaPolicy.coordinatorSlaPolicy.coordinatorUrl}</td> + </tr>, + <tr> + <td>status key</td> + <td>{config.slaPolicy.coordinatorSlaPolicy.statusKey}</td> + </tr>]; + } + + return null; +} /* eslint-enable */ export function CronConfigSummary({ cronJob }) { @@ -108,6 +148,7 @@ export function CronConfigSummary({ cronJob }) { </tr> <Metadata config={config} /> <PartitionPolicy config={config} /> + <SlaPolicy config={config} /> <tr> <th>Contact</th> <td colSpan='2'>{config.contactEmail}</td> @@ -136,6 +177,7 @@ export default function TaskConfigSummary({ config, instances }) { </tr> <Metadata config={config} /> <PartitionPolicy config={config} /> + <SlaPolicy config={config} /> <tr> <th>Contact</th> <td colSpan='2'>{config.contactEmail}</td>
