[autotest] [atomic] Remove atomic groups from cli

BUG=chromium:681906
TEST=Run unittest suite

Change-Id: I2f9edaa074e4ce7f7d658f79d1256413c34a7a1c
Reviewed-on: https://chromium-review.googlesource.com/434108
Commit-Ready: Allen Li <ayatane@chromium.org>
Tested-by: Allen Li <ayatane@chromium.org>
Reviewed-by: Richard Barnette <jrbarnette@google.com>
diff --git a/cli/action_common.py b/cli/action_common.py
index c7fbaf0..ce02007 100644
--- a/cli/action_common.py
+++ b/cli/action_common.py
@@ -184,7 +184,7 @@
 
 #
 # Adding or Removing things (users, hosts or labels) from a topic
-# (ACL, Label or AtomicGroup)
+# (ACL or Label)
 #
 class atest_add_or_remove(topic_common.atest):
     """atest <topic> [add|remove]
diff --git a/cli/atest_unittest.py b/cli/atest_unittest.py
index 2e3f0a0..7df6683 100755
--- a/cli/atest_unittest.py
+++ b/cli/atest_unittest.py
@@ -9,7 +9,7 @@
 import common
 from autotest_lib.cli import cli_mock
 
-ATEST_USAGE_STRING = ('atest [acl|host|job|label|shard|atomicgroup|test|user|'
+ATEST_USAGE_STRING = ('atest [acl|host|job|label|shard|test|user|'
                       'server|stable_version] [action] [options]')
 
 class main_unittest(cli_mock.cli_unittest):
diff --git a/cli/atomicgroup.py b/cli/atomicgroup.py
deleted file mode 100644
index 580fc5d..0000000
--- a/cli/atomicgroup.py
+++ /dev/null
@@ -1,148 +0,0 @@
-
-"""
-The atomicgroup module contains the objects and methods used to
-manage atomic groups in Autotest.
-
-The valid actions are:
-create:  Create a new atomic group.
-delete:  Delete (invalidate) an existing atomic group.
-list:    Lists atomic groups.
-add:     Adds labels to an atomic group.
-remove:  Removes labels from an atomic group.
-
-See topic_common.py for a High Level Design and Algorithm.
-"""
-
-import os, sys
-from autotest_lib.cli import topic_common, action_common
-
-class atomicgroup(topic_common.atest):
-    """
-    Atomic group class
-
-    atest atomicgroup [create|delete|list|add|remove] <options>
-    """
-    usage_action = '[create|delete|list|add|remove]'
-    topic = 'atomic_group'
-    msg_topic = 'atomicgroup'
-    msg_items = '<atomicgroups>'
-
-
-    def __init__(self):
-        super(atomicgroup, self).__init__()
-        self.parser.add_option('-G', '--glist',
-                               help='File listing the ATOMIC GROUPs',
-                               type='string', default=None,
-                               metavar='ATOMIC_GROUP_FLIST')
-
-        self.topic_parse_info = topic_common.item_parse_info(
-            attribute_name='atomicgroups',
-            filename_option='glist',
-            use_leftover=True)
-
-
-    def get_items(self):
-        return self.atomicgroups
-
-
-class atomicgroup_help(atomicgroup):
-    """Just to get the atest logic working.  Usage is set by its parent."""
-    pass
-
-
-class atomicgroup_list(action_common.atest_list, atomicgroup):
-    """atest atomicgroup list [--show-invalid]"""
-    def __init__(self):
-        super(atomicgroup_list, self).__init__()
-        self.parser.add_option('-d', '--show-invalid',
-                               help='Don\'t hide invalid atomic groups.',
-                               action='store_true')
-
-
-    def parse(self):
-        options, leftover = super(atomicgroup_list, self).parse()
-        self.show_invalid = options.show_invalid
-        return options, leftover
-
-
-    def execute(self):
-        return super(atomicgroup_list, self).execute(op='get_atomic_groups')
-
-
-    def output(self, results):
-        if not self.show_invalid:
-            results = [atomicgroup for atomicgroup in results
-                       if not atomicgroup['invalid']]
-
-        keys = ['name', 'description', 'max_number_of_machines', 'invalid']
-        super(atomicgroup_list, self).output(results, keys)
-
-
-class atomicgroup_create(action_common.atest_create, atomicgroup):
-    def __init__(self):
-        super(atomicgroup_create, self).__init__()
-        self.parser.add_option('-n', '--max_number_of_machines',
-                               help='Maximum # of machines for this group.',
-                               type='int', default=None)
-        self.parser.add_option('-d', '--description',
-                               help='Description of this atomic group.',
-                               type='string', default='')
-
-
-    def parse(self):
-        options, leftover = super(atomicgroup_create, self).parse()
-        self.data_item_key = 'name'
-        self.data['description'] = options.description
-        self.data['max_number_of_machines'] = options.max_number_of_machines
-        return options, leftover
-
-
-class atomicgroup_delete(action_common.atest_delete, atomicgroup):
-    """atest atomicgroup delete <atomicgroup>"""
-    pass
-
-
-class atomicgroup_add_or_remove(atomicgroup):
-
-    def __init__(self):
-        super(atomicgroup_add_or_remove, self).__init__()
-        # .add_remove_things is used by action_common.atest_add_or_remove.
-        self.add_remove_things = {'labels': 'label'}
-        lower_words = tuple(word.lower() for word in self.usage_words)
-        self.parser.add_option('-l', '--label',
-                               help=('%s LABELS(s) %s the ATOMIC GROUP.' %
-                                     self.usage_words),
-                               type='string',
-                               metavar='LABEL')
-        self.parser.add_option('-L', '--label_list',
-                               help='File containing LABELs to %s %s '
-                               'the ATOMIC GROUP.' % lower_words,
-                               type='string',
-                               metavar='LABEL_FLIST')
-
-
-    def parse(self):
-        label_info = topic_common.item_parse_info(attribute_name='labels',
-                                                  inline_option='label',
-                                                  filename_option='label_list')
-
-        options, leftover = super(atomicgroup_add_or_remove,
-                                  self).parse([label_info],
-                                              req_items='atomicgroups')
-        if not getattr(self, 'labels', None):
-            self.invalid_syntax('%s %s requires at least one label' %
-                                (self.msg_topic,
-                                 self.usage_action))
-        return options, leftover
-
-
-class atomicgroup_add(action_common.atest_add, atomicgroup_add_or_remove):
-    """atest atomicgroup add <atomicgroup>
-     [--label <label>] [--label_list <file>]"""
-    pass
-
-
-class atomicgroup_remove(action_common.atest_remove, atomicgroup_add_or_remove):
-    """atest atomicgroup remove <atomicgroup>
-     [--label <label>] [--label_list <file>]"""
-    pass
diff --git a/cli/atomicgroup_unittest.py b/cli/atomicgroup_unittest.py
deleted file mode 100755
index 3c5faef..0000000
--- a/cli/atomicgroup_unittest.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# pylint: disable-msg=C0111
-#!/usr/bin/python -u
-
-"""Tests for atomicgroup."""
-
-import unittest
-
-import common
-from autotest_lib.cli import cli_mock
-
-
-class atomicgroup_unittest(cli_mock.cli_unittest):
-    def setUp(self):
-        super(atomicgroup_unittest, self).setUp()
-
-
-    def run_cmd(self, argv, *args, **kwargs):
-        atomicgroup_argv = ['atest', 'atomicgroup'] + argv
-        super(atomicgroup_unittest, self).run_cmd(
-                argv=atomicgroup_argv, *args, **kwargs)
-
-
-    atomicgroups = [
-                {'name': 'group0',
-                 'description': 'description0',
-                 'max_number_of_machines': 3,
-                 'invalid': True},
-                {'name': 'group1',
-                 'description': 'description1',
-                 'max_number_of_machines': 13,
-                 'invalid': False},
-                {'name': 'group2',
-                 'description': 'description2',
-                 'max_number_of_machines': 23,
-                 'invalid': False},
-            ]
-
-
-    def test_atomicgroup_list(self):
-        valid_groups = [ag for ag in self.atomicgroups if not ag['invalid']]
-        self.run_cmd(argv=['list'],
-                     rpcs=[('get_atomic_groups', {},
-                            True, valid_groups)],
-                     out_words_ok=['group1', 'description2', '23', 'True'],
-                     out_words_no=['group0', 'description0', 'False'],
-                    )
-
-
-    def test_atomicgroup_list_show_invalid(self):
-        self.run_cmd(argv=['list', '--show-invalid'],
-                     rpcs=[('get_atomic_groups', {},
-                            True, self.atomicgroups)],
-                     out_words_ok=['group1', 'description2', '23', 'True'],
-                    )
-
-
-    def test_atomicgroup_create(self):
-        self.run_cmd(argv=['create', '-n', '33', '-d', 'Fruits', 'ag-name'],
-                     rpcs=[('add_atomic_group',
-                            dict(name='ag-name', description='Fruits',
-                                 max_number_of_machines=33),
-                            True, 1)],
-                     out_words_ok=['Created', 'atomicgroup', 'ag-name'],
-                    )
-
-    def test_atomicgroup_create_longargs(self):
-        self.run_cmd(argv=['create', '--max_number_of_machines', '33',
-                           '--description', 'Fruits', 'ag-name'],
-                     rpcs=[('add_atomic_group',
-                            dict(name='ag-name', description='Fruits',
-                                 max_number_of_machines=33),
-                            True, 1)],
-                     out_words_ok=['Created', 'atomicgroup', 'ag-name'],
-                    )
-
-
-    def test_atomicgroup_delete(self):
-        self.run_cmd(argv=['delete', 'ag-name', '--no-confirmation'],
-                     rpcs=[('delete_atomic_group', dict(id='ag-name'),
-                            True, None)],
-                     out_words_ok=['Deleted', 'atomicgroup', 'ag-name'],
-                    )
-
-
-    def test_atomicgroup_add(self):
-        self.run_cmd(argv=['add', '--label', 'One', 'ag-name'],
-                     rpcs=[('atomic_group_add_labels',
-                            dict(id='ag-name', labels=['One']),
-                            True, None)],
-                     out_words_ok=['Added', 'atomicgroup', 'ag-name'],
-                    )
-
-    def test_atomicgroup_remove(self):
-        self.run_cmd(argv=['remove', '--label', 'One', 'ag-name'],
-                     rpcs=[('atomic_group_remove_labels',
-                            dict(id='ag-name', labels=['One']),
-                            True, None)],
-                     out_words_ok=['Removed', 'atomicgroup', 'ag-name'],
-                    )
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/cli/job.py b/cli/job.py
index d7df744..1c8cee1 100644
--- a/cli/job.py
+++ b/cli/job.py
@@ -364,7 +364,7 @@
     [--noverify] [--timeout <timeout>] [--max_runtime <max runtime>]
     [--one-time-hosts <hosts>] [--email <email>]
     [--dependencies <labels this job is dependent on>]
-    [--atomic_group <atomic group name>] [--parse-failed-repair <option>]
+    [--parse-failed-repair <option>]
     [--image <http://path/to/image>] [--require-ssp]
     job_name
 
@@ -390,9 +390,6 @@
         self.parser.add_option('-d', '--dependencies', help='Comma separated '
                                'list of labels this job is dependent on.',
                                default='')
-        self.parser.add_option('-G', '--atomic_group', help='Name of an Atomic '
-                               'Group to schedule this job on.',
-                               default='')
 
         self.parser.add_option('-B', '--reboot_before',
                                help='Whether or not to reboot the machine '
@@ -436,10 +433,9 @@
                 parse_info=[deps_info])
 
         if (len(self.hosts) == 0 and not self.one_time_hosts
-            and not options.labels and not options.atomic_group):
-            self.invalid_syntax('Must specify at least one machine '
-                                'or an atomic group '
-                                '(-m, -M, -b, -G or --one-time-hosts).')
+            and not options.labels):
+            self.invalid_syntax('Must specify at least one machine.'
+                                '(-m, -M, -b or --one-time-hosts).')
         if not options.control_file and not options.test:
             self.invalid_syntax('Must specify either --test or --control-file'
                                 ' to create a job.')
@@ -482,9 +478,6 @@
         if options.max_runtime:
             self.data['max_runtime_mins'] = options.max_runtime
 
-        if options.atomic_group:
-            self.data['atomic_group_name'] = options.atomic_group
-
         self.data['dependencies'] = self.dependencies
 
         if options.synch_count:
diff --git a/cli/job_unittest.py b/cli/job_unittest.py
index 652987b..2279407 100755
--- a/cli/job_unittest.py
+++ b/cli/job_unittest.py
@@ -758,29 +758,6 @@
                      out_words_no=['Uploading', 'Done'])
 
 
-    def test_execute_create_job_with_atomic_group(self):
-        data = dict(self.data)
-        data['atomic_group_name'] = 'my-atomic-group'
-        data['control_type'] = SERVER
-        mock_ctrl_file = 'mock control file'
-        data['control_file'] = mock_ctrl_file
-        data['synch_count'] = 2
-        data['hosts'] = []
-        self.run_cmd(argv=['atest', 'job', 'create', '-t', 'mocktest',
-                           'test_job0', '--ignore_site_file',
-                           '-G', 'my-atomic-group'],
-                     rpcs=[('generate_control_file',
-                            {'tests': ['mocktest']},
-                            True,
-                            {'control_file' : mock_ctrl_file,
-                             'synch_count' : 2,
-                             'is_server' : True,
-                             'dependencies' : []}),
-                           ('create_job', data, True, 180)],
-                     out_words_ok=['test_job0', 'Created'],
-                     out_words_no=['Uploading', 'Done'])
-
-
     def test_execute_create_job_with_control(self):
         file_temp = cli_mock.create_file(self.ctrl_file)
         self.run_cmd(argv=['atest', 'job', 'create', '-f', file_temp.name,
@@ -1191,7 +1168,6 @@
                     'timeout_mins': 480}
 
     local_hosts = [{u'acls': [u'acl0'],
-                    u'atomic_group': None,
                     u'attributes': {},
                     u'dirty': False,
                     u'hostname': u'host0',
@@ -1207,7 +1183,6 @@
                     u'status': u'Ready',
                     u'synch_id': None},
                    {u'acls': [u'acl0'],
-                    u'atomic_group': None,
                     u'attributes': {},
                     u'dirty': False,
                     u'hostname': u'host1',
@@ -1244,9 +1219,7 @@
                      rpcs=[('get_info_for_clone', {'id': '42',
                                                    'preserve_metahosts': True},
                             True,
-                            {u'atomic_group_name': None,
-                             u'hosts': [{u'acls': [u'acl0'],
-                                         u'atomic_group': None,
+                            {u'hosts': [{u'acls': [u'acl0'],
                                          u'attributes': {},
                                          u'dirty': False,
                                          u'hostname': u'host0',
@@ -1274,8 +1247,7 @@
                      rpcs=[('get_info_for_clone', {'id': '42',
                                                    'preserve_metahosts': True},
                             True,
-                            {u'atomic_group_name': None,
-                             u'hosts': self.local_hosts,
+                            {u'hosts': self.local_hosts,
                              u'job': self.job_data_clone_info,
                              u'meta_host_counts': {}}),
                            ('create_job', self.job_data_cloned, True, 43)],
@@ -1290,8 +1262,7 @@
                      rpcs=[('get_info_for_clone', {'id': '42',
                                                    'preserve_metahosts': True},
                             True,
-                            {u'atomic_group_name': None,
-                             u'hosts': [],
+                            {u'hosts': [],
                              u'job': self.job_data_clone_info,
                              u'meta_host_counts': {u'type0': 1,
                                                    u'type1': 4}}),
@@ -1307,7 +1278,7 @@
                      rpcs=[('get_info_for_clone', {'id': '42',
                                                    'preserve_metahosts': True},
                             True,
-                            {u'atomic_group_name': None,
+                            {
                              u'hosts': self.local_hosts,
                              u'job': self.job_data_clone_info,
                              u'meta_host_counts': {u'type0': 1,
@@ -1338,8 +1309,7 @@
                      rpcs=[('get_info_for_clone', {'id': '42',
                                                    'preserve_metahosts': False},
                             True,
-                            {u'atomic_group_name': None,
-                             u'hosts': self.local_hosts,
+                            {u'hosts': self.local_hosts,
                              u'job': self.job_data_clone_info,
                              u'meta_host_counts': {}}),
                            ('create_job', self.job_data_cloned, True, 43)],
@@ -1354,8 +1324,7 @@
                      rpcs=[('get_info_for_clone', {'id': '42',
                                                    'preserve_metahosts': False},
                             True,
-                            {u'atomic_group_name': None,
-                             u'hosts': self.local_hosts,
+                            {u'hosts': self.local_hosts,
                              u'job': self.job_data_clone_info,
                              u'meta_host_counts': {}}),
                            ('create_job', self.job_data_cloned, True, 43)],
diff --git a/cli/label.py b/cli/label.py
index 65ad468..e4844c3 100644
--- a/cli/label.py
+++ b/cli/label.py
@@ -16,7 +16,7 @@
 See topic_common.py for a High Level Design and Algorithm.
 """
 
-import os, sys
+import sys
 from autotest_lib.cli import topic_common, action_common
 
 
@@ -55,7 +55,7 @@
 
 
 class label_list(action_common.atest_list, label):
-    """atest label list [--platform] [--all] [--atomicgroup]
+    """atest label list [--platform] [--all]
     [--valid-only] [--machine <machine>]
     [--blist <file>] [<labels>]"""
     def __init__(self):
@@ -74,11 +74,6 @@
                                      'platform labels'),
                                action='store_true')
 
-        self.parser.add_option('--atomicgroup',
-                               help=('Display only atomic group labels '
-                                     'along with the atomic group name.'),
-                               action='store_true')
-
         self.parser.add_option('-m', '--machine',
                                help='List LABELs of MACHINE',
                                type='string',
@@ -90,10 +85,10 @@
                                                  inline_option='machine')
         (options, leftover) = super(label_list, self).parse([host_info])
 
-        exclusives = [options.all, options.platform_only, options.atomicgroup]
+        exclusives = [options.all, options.platform_only]
         if exclusives.count(True) > 1:
             self.invalid_syntax('Only specify one of --all,'
-                                '--platform, --atomicgroup')
+                                '--platform')
 
         if len(self.hosts) > 1:
             self.invalid_syntax(('Only one machine name allowed. '
@@ -101,7 +96,6 @@
                                  'instead.') %
                                 (sys.argv[0], ','.join(self.hosts)))
         self.all = options.all
-        self.atomicgroup = options.atomicgroup
         self.platform_only = options.platform_only
         self.valid_only = options.valid_only
         return (options, leftover)
@@ -132,10 +126,6 @@
             results = [label for label in results
                        if label['platform']]
             keys = ['name', 'invalid']
-        elif self.atomicgroup:
-            results = [label for label in results
-                       if label['atomic_group']]
-            keys = ['name', 'atomic_group.name', 'invalid']
         elif not self.all:
             results = [label for label in results
                        if not label['platform']]
@@ -176,6 +166,7 @@
 
 
 class label_add_or_remove(label):
+    """Parent for `atest label` add and `label remove`"""
     def __init__(self):
         super(label_add_or_remove, self).__init__()
         lower_words = tuple(word.lower() for word in self.usage_words)
diff --git a/cli/topic_common.py b/cli/topic_common.py
index 7762a75..13d4c07 100644
--- a/cli/topic_common.py
+++ b/cli/topic_common.py
@@ -108,7 +108,6 @@
                     'synch_count': 'Sync Count',
                     'max_number_of_machines': 'Max. hosts to use',
                     'parse_failed_repair': 'Include failed repair results',
-                    'atomic_group.name': 'Atomic Group Name',
                     'shard': 'Shard',
                     }
 
@@ -254,7 +253,7 @@
     Should only be instantiated by itself for usage
     references, otherwise, the <topic> objects should
     be used."""
-    msg_topic = ('[acl|host|job|label|shard|atomicgroup|test|user|server|'
+    msg_topic = ('[acl|host|job|label|shard|test|user|server|'
                  'stable_version]')
     usage_action = '[action]'
     msg_items = ''