TestInventory.py 14 KB
Newer Older
1 2
import os
import unittest
3
from nose.tools import raises
4

5
from ansible import errors
6 7 8 9 10 11 12 13
from ansible.inventory import Inventory

class TestInventory(unittest.TestCase):

    def setUp(self):
        self.cwd = os.getcwd()
        self.test_dir = os.path.join(self.cwd, 'test')

14 15 16 17
        self.inventory_file             = os.path.join(self.test_dir, 'simple_hosts')
        self.large_range_inventory_file = os.path.join(self.test_dir, 'large_range')
        self.complex_inventory_file     = os.path.join(self.test_dir, 'complex_hosts')
        self.inventory_script           = os.path.join(self.test_dir, 'inventory_api.py')
18
        self.inventory_dir              = os.path.join(self.test_dir, 'inventory_dir')
19 20 21 22 23 24

        os.chmod(self.inventory_script, 0755)

    def tearDown(self):
        os.chmod(self.inventory_script, 0644)

25 26 27 28
    def compare(self, left, right, sort=True):
        if sort:
            left = sorted(left)
            right = sorted(right)
29 30 31 32
        print left
        print right
        assert left == right

33 34 35
    def empty_inventory(self):
        return Inventory(None)

36
    def simple_inventory(self):
37
        return Inventory(self.inventory_file)
38

39 40 41
    def large_range_inventory(self):
        return Inventory(self.large_range_inventory_file)

42
    def script_inventory(self):
43
        return Inventory(self.inventory_script)
44

45 46 47
    def complex_inventory(self):
        return Inventory(self.complex_inventory_file)

48 49 50
    def dir_inventory(self):
        return Inventory(self.inventory_dir)

51 52 53 54 55 56 57 58 59
    all_simple_hosts=['jupiter', 'saturn', 'zeus', 'hera',
            'cerberus001','cerberus002','cerberus003',
            'cottus99', 'cottus100',
            'poseidon', 'thor', 'odin', 'loki',
            'thrudgelmir0', 'thrudgelmir1', 'thrudgelmir2',
            'thrudgelmir3', 'thrudgelmir4', 'thrudgelmir5',
            'Hotep-a', 'Hotep-b', 'Hotep-c',
            'BastC', 'BastD', ]

60
    #####################################
61 62 63 64 65 66 67 68
    ### Empty inventory format tests

    def test_empty(self):
        inventory = self.empty_inventory()
        hosts = inventory.list_hosts()
        self.assertEqual(hosts, [])

    #####################################
69
    ### Simple inventory format tests
70

71 72 73
    def test_simple(self):
        inventory = self.simple_inventory()
        hosts = inventory.list_hosts()
74
        self.assertEqual(sorted(hosts), sorted(self.all_simple_hosts))
75 76 77 78

    def test_simple_all(self):
        inventory = self.simple_inventory()
        hosts = inventory.list_hosts('all')
79
        self.assertEqual(sorted(hosts), sorted(self.all_simple_hosts))
80

81 82 83 84 85 86 87 88 89 90
    def test_get_hosts(self):
        inventory = Inventory('127.0.0.1,192.168.1.1')
        hosts = inventory.get_hosts('!10.0.0.1')
        hosts_all = inventory.get_hosts('all')
        self.assertEqual(sorted(hosts), sorted(hosts_all))

    def test_no_src(self):
        inventory = Inventory('127.0.0.1,')
        self.assertEqual(inventory.src(), None)

91 92 93 94 95
    def test_simple_norse(self):
        inventory = self.simple_inventory()
        hosts = inventory.list_hosts("norse")

        expected_hosts=['thor', 'odin', 'loki']
96
        assert sorted(hosts) == sorted(expected_hosts)
97

98 99 100 101
    def test_simple_ungrouped(self):
        inventory = self.simple_inventory()
        hosts = inventory.list_hosts("ungrouped")

Michael DeHaan committed
102 103
        expected_hosts=['jupiter', 'saturn',
                        'thrudgelmir0', 'thrudgelmir1', 'thrudgelmir2',
104
                        'thrudgelmir3', 'thrudgelmir4', 'thrudgelmir5']
105
        assert sorted(hosts) == sorted(expected_hosts)
106

107 108 109 110
    def test_simple_combined(self):
        inventory = self.simple_inventory()
        hosts = inventory.list_hosts("norse:greek")

Michael DeHaan committed
111
        expected_hosts=['zeus', 'hera', 'poseidon',
112 113 114
                        'cerberus001','cerberus002','cerberus003',
                        'cottus99','cottus100',
                        'thor', 'odin', 'loki']
115
        assert sorted(hosts) == sorted(expected_hosts)
116 117 118 119 120

    def test_simple_restrict(self):
        inventory = self.simple_inventory()

        restricted_hosts = ['hera', 'poseidon', 'thor']
Michael DeHaan committed
121
        expected_hosts=['zeus', 'hera', 'poseidon',
122 123 124
                        'cerberus001','cerberus002','cerberus003',
                        'cottus99', 'cottus100',
                        'thor', 'odin', 'loki']
125 126 127 128

        inventory.restrict_to(restricted_hosts)
        hosts = inventory.list_hosts("norse:greek")

129
        assert sorted(hosts) == sorted(restricted_hosts)
130 131 132 133

        inventory.lift_restriction()
        hosts = inventory.list_hosts("norse:greek")

134
        assert sorted(hosts) == sorted(expected_hosts)
135

136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
    def test_simple_string_ipv4(self):
        inventory = Inventory('127.0.0.1,192.168.1.1')
        hosts = inventory.list_hosts()
        self.assertEqual(sorted(hosts), sorted(['127.0.0.1','192.168.1.1']))

    def test_simple_string_ipv4_port(self):
        inventory = Inventory('127.0.0.1:2222,192.168.1.1')
        hosts = inventory.list_hosts()
        self.assertEqual(sorted(hosts), sorted(['127.0.0.1','192.168.1.1']))

    def test_simple_string_ipv4_vars(self):
        inventory = Inventory('127.0.0.1:2222,192.168.1.1')
        var = inventory.get_variables('127.0.0.1')
        self.assertEqual(var['ansible_ssh_port'], 2222)

    def test_simple_string_ipv6(self):
        inventory = Inventory('FE80:EF45::12:1,192.168.1.1')
        hosts = inventory.list_hosts()
        self.assertEqual(sorted(hosts), sorted(['FE80:EF45::12:1','192.168.1.1']))

    def test_simple_string_ipv6_port(self):
        inventory = Inventory('[FE80:EF45::12:1]:2222,192.168.1.1')
        hosts = inventory.list_hosts()
        self.assertEqual(sorted(hosts), sorted(['FE80:EF45::12:1','192.168.1.1']))

    def test_simple_string_ipv6_vars(self):
        inventory = Inventory('[FE80:EF45::12:1]:2222,192.168.1.1')
        var = inventory.get_variables('FE80:EF45::12:1')
        self.assertEqual(var['ansible_ssh_port'], 2222)

166 167 168 169
    def test_simple_vars(self):
        inventory = self.simple_inventory()
        vars = inventory.get_variables('thor')

170
        assert vars == {'group_names': ['norse'],
171 172
                        'inventory_hostname': 'thor',
                        'inventory_hostname_short': 'thor'}
173

174 175 176 177
    def test_simple_port(self):
        inventory = self.simple_inventory()
        vars = inventory.get_variables('hera')

178 179 180 181
        expected = { 'ansible_ssh_port': 3000,
                     'group_names': ['greek'],
                     'inventory_hostname': 'hera',
                     'inventory_hostname_short': 'hera' }
182
        assert vars == expected
183

184 185 186 187 188
    def test_large_range(self):
        inventory = self.large_range_inventory()
        hosts = inventory.list_hosts()
        self.assertEqual(sorted(hosts),  sorted('bob%03i' %i  for i in range(0, 143)))

189 190 191 192 193 194 195 196 197 198 199 200 201 202
    def test_subset(self):
        inventory = self.simple_inventory()
        inventory.subset('odin;thor,loki')
        self.assertEqual(sorted(inventory.list_hosts()),  sorted(['thor','odin','loki']))

    def test_subset_filename(self):
        inventory = self.simple_inventory()
        inventory.subset('@' + os.path.join(self.test_dir, 'restrict_pattern'))
        self.assertEqual(sorted(inventory.list_hosts()),  sorted(['thor','odin']))

    @raises(errors.AnsibleError)
    def testinvalid_entry(self):
       Inventory('1234')

203 204 205 206 207 208 209 210 211 212
    ###################################################
    ### INI file advanced tests

    def test_complex_vars(self):
        inventory = self.complex_inventory()

        vars = inventory.get_variables('rtp_a')
        print vars

        expected = dict(
213 214 215
            a='1', b='2', c='3', d='10002', e='10003', f='10004 != 10005',
            g='  g  ', h='  h  ', i="'  i  \"", j='"  j',
            rga='1', rgb='2', rgc='3',
Michael DeHaan committed
216
            inventory_hostname='rtp_a', inventory_hostname_short='rtp_a',
217
            group_names=[ 'eastcoast', 'nc', 'redundantgroup', 'redundantgroup2', 'redundantgroup3', 'rtp', 'us' ]
218 219 220 221 222
        )
        print vars
        print expected
        assert vars == expected

223 224 225
    def test_complex_group_names(self):
        inventory = self.complex_inventory()
        tests = {
226
            'host1': [ 'role1', 'role3' ],
227
            'host2': [ 'role1', 'role2' ],
228
            'host3': [ 'role2', 'role3' ]
229 230 231 232 233
        }
        for host, roles in tests.iteritems():
            group_names = inventory.get_variables(host)['group_names']
            assert sorted(group_names) == sorted(roles)

234 235
    def test_complex_exclude(self):
        inventory = self.complex_inventory()
236
        hosts = inventory.list_hosts("nc:florida:!triangle:!orlando")
237
        expected_hosts = ['miami', 'rtp_a', 'rtp_b', 'rtp_c']
238 239
        print "HOSTS=%s" % sorted(hosts)
        print "EXPECTED=%s" % sorted(expected_hosts)
240 241
        assert sorted(hosts) == sorted(expected_hosts)

242 243 244 245 246 247 248 249
    def test_regex_exclude(self):
        inventory = self.complex_inventory()
        hosts = inventory.list_hosts("~rtp_[ac]")
        expected_hosts = ['rtp_a', 'rtp_c']
        print "HOSTS=%s" % sorted(hosts)
        print "EXPECTED=%s" % sorted(expected_hosts)
        assert sorted(hosts) == sorted(expected_hosts)

250 251 252
    def test_complex_enumeration(self):


253 254 255 256
        expected1 = ['rtp_b']
        expected2 = ['rtp_a', 'rtp_b']
        expected3 = ['rtp_a', 'rtp_b', 'rtp_c', 'tri_a', 'tri_b', 'tri_c']
        expected4 = ['rtp_b', 'orlando' ]
257 258

        inventory = self.complex_inventory()
259
        hosts = inventory.list_hosts("nc[1]")
260
        self.compare(hosts, expected1, sort=False)
261
        hosts = inventory.list_hosts("nc[0-2]")
262
        self.compare(hosts, expected2, sort=False)
263
        hosts = inventory.list_hosts("nc[0-99999]")
264
        self.compare(hosts, expected3, sort=False)
265
        hosts = inventory.list_hosts("nc[1-2]:florida[0-1]")
266 267
        self.compare(hosts, expected4, sort=False)

268 269 270 271 272 273 274
    def test_complex_intersect(self):
        inventory = self.complex_inventory()
        hosts = inventory.list_hosts("nc:&redundantgroup:!rtp_c")
        self.compare(hosts, ['rtp_a'])
        hosts = inventory.list_hosts("nc:&triangle:!tri_c")
        self.compare(hosts, ['tri_a', 'tri_b'])

275 276 277
    @raises(errors.AnsibleError)
    def test_invalid_range(self):
        Inventory(os.path.join(self.test_dir, 'inventory','test_incorrect_range'))
278

279 280 281 282
    @raises(errors.AnsibleError)
    def test_missing_end(self):
        Inventory(os.path.join(self.test_dir, 'inventory','test_missing_end'))

283 284 285 286
    @raises(errors.AnsibleError)
    def test_incorrect_format(self):
        Inventory(os.path.join(self.test_dir, 'inventory','test_incorrect_format'))

287 288 289 290
    @raises(errors.AnsibleError)
    def test_alpha_end_before_beg(self):
        Inventory(os.path.join(self.test_dir, 'inventory','test_alpha_end_before_beg'))

291 292 293 294 295
    def test_combined_range(self):
        i = Inventory(os.path.join(self.test_dir, 'inventory','test_combined_range'))
        hosts = i.list_hosts('test')
        expected_hosts=['host1A','host2A','host1B','host2B']
        assert sorted(hosts) == sorted(expected_hosts)
296

297
    ###################################################
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
    ### Inventory API tests

    def test_script(self):
        inventory = self.script_inventory()
        hosts = inventory.list_hosts()

        expected_hosts=['jupiter', 'saturn', 'zeus', 'hera', 'poseidon', 'thor', 'odin', 'loki']

        print "Expected: %s"%(expected_hosts)
        print "Got     : %s"%(hosts)
        assert sorted(hosts) == sorted(expected_hosts)

    def test_script_all(self):
        inventory = self.script_inventory()
        hosts = inventory.list_hosts('all')

        expected_hosts=['jupiter', 'saturn', 'zeus', 'hera', 'poseidon', 'thor', 'odin', 'loki']
        assert sorted(hosts) == sorted(expected_hosts)

    def test_script_norse(self):
        inventory = self.script_inventory()
        hosts = inventory.list_hosts("norse")

        expected_hosts=['thor', 'odin', 'loki']
        assert sorted(hosts) == sorted(expected_hosts)

    def test_script_combined(self):
        inventory = self.script_inventory()
        hosts = inventory.list_hosts("norse:greek")

        expected_hosts=['zeus', 'hera', 'poseidon', 'thor', 'odin', 'loki']
        assert sorted(hosts) == sorted(expected_hosts)

    def test_script_restrict(self):
        inventory = self.script_inventory()

        restricted_hosts = ['hera', 'poseidon', 'thor']
        expected_hosts=['zeus', 'hera', 'poseidon', 'thor', 'odin', 'loki']

        inventory.restrict_to(restricted_hosts)
        hosts = inventory.list_hosts("norse:greek")

        assert sorted(hosts) == sorted(restricted_hosts)

        inventory.lift_restriction()
        hosts = inventory.list_hosts("norse:greek")

        assert sorted(hosts) == sorted(expected_hosts)

    def test_script_vars(self):
        inventory = self.script_inventory()
        vars = inventory.get_variables('thor')

351 352
        print "VARS=%s" % vars

353 354
        assert vars == {'hammer':True,
                        'group_names': ['norse'],
355 356
                        'inventory_hostname': 'thor',
                        'inventory_hostname_short': 'thor'}
357 358

    def test_hosts_list(self):
Michael DeHaan committed
359
        # Test the case when playbook 'hosts' var is a list.
360 361 362 363 364
        inventory = self.script_inventory()
        host_names = sorted(['thor', 'loki', 'odin'])       # Not sure if sorting is in the contract or not
        actual_hosts = inventory.get_hosts(host_names)
        actual_host_names = [host.name for host in actual_hosts]
        assert host_names == actual_host_names
365 366 367 368 369 370

    def test_script_multiple_groups(self):
        inventory = self.script_inventory()
        vars = inventory.get_variables('zeus')

        print "VARS=%s" % vars
371

372 373 374
        assert vars == {'inventory_hostname': 'zeus',
                        'inventory_hostname_short': 'zeus',
                        'group_names': ['greek', 'major-god']}
375

Michael DeHaan committed
376 377 378 379 380 381 382 383 384 385 386 387
    # test disabled as needs to be updated to model desired behavior
    #
    #def test_dir_inventory(self):
    #    inventory = self.dir_inventory()
    #    vars = inventory.get_variables('zeus')
    #
    #   print "VARS=%s" % vars
    #
    #    assert vars == {'inventory_hostname': 'zeus',
    #                    'inventory_hostname_short': 'zeus',
    #                    'group_names': ['greek', 'major-god', 'ungrouped'],
    #                    'var_a': '1#2'}