Example #1
0
def gen_random_inventory(tmp_path):
    """Generate a random inventory, write the files and return the resulting
    inventory, the directory containing the files and the key for credential
    decryption
    """
    inventory, credentials, result = get_random_node_list(INVENTORY_SIZE)
    # Generate the inventory files
    # Write the inventory file
    inv_data = yaml.safe_dump(inventory)
    if not inv_data:
        assert False, "Unable to produce the device list"
    with open(f'{tmp_path}/inv_0.yml', "w") as out_file:
        out_file.write(inv_data)

    # Encrypt and write the credential file
    cred_key = Fernet.generate_key()
    encryptor = Fernet(cred_key)

    cred_data = yaml.safe_dump(credentials)
    if not cred_data:
        assert False, "Unable to produce the credentials list"
    # Encrypt credential data
    enc_cred_data = encryptor.encrypt(cred_data.encode('utf-8'))
    with open(f'{tmp_path}/cred_0', "w") as out_file:
        out_file.write(enc_cred_data.decode())

    return result, tmp_path, cred_key.decode()
Example #2
0
async def test_launch_debug_mode(monkeypatch, manager_cfg, capsys):
    """Test the debug mode, check if no worker is launched and if the help
    message have been printed
    """
    fake_environ = {}
    monkeypatch.setattr(os, 'environ', fake_environ)

    manager_args = MANAGER_ARGS.copy()
    manager_args['debug'] = True
    manager_args['workers'] = 2
    manager = init_static_manager(manager_cfg, manager_args)

    _, _, chunk1 = get_random_node_list(1)
    _, _, chunk2 = get_random_node_list(1)
    inventory = [chunk1, chunk2]

    launch_fn, stop_fn, \
        write_chunk_fn = await apply_with_mocks(manager, inventory)

    # Check if no worker has been launched
    launch_fn.assert_not_called()
    stop_fn.assert_not_called()

    # Check if chunks have been written
    for i, c in enumerate(inventory):
        write_chunk_fn.assert_any_call(i, c)

    help_message = capsys.readouterr().out
    # Make sure an output have been returned
    assert help_message, 'No help message printed'
    worker_messages = help_message.split('\n\n')

    # Check if the number of messages is equal to the number of workers
    expected_lines = manager_args['workers']
    # We need to remove the very first line
    obtained_lines = len(worker_messages) - 1
    assert expected_lines == obtained_lines, \
           f"Expected {expected_lines} commands, {obtained_lines} obtained"
Example #3
0
async def test_inventory_apply(monkeypatch, manager_cfg):
    """Check if the inventory is correctly applied
    """
    fake_environ = {}
    monkeypatch.setattr(os, 'environ', fake_environ)

    manager = init_static_manager(manager_cfg)
    _, _, inventory = get_random_node_list(20)

    launch_fn, stop_fn, \
        write_chunk_fn = await apply_with_mocks(manager, [inventory])

    # Check if poller have been correctly called
    launch_fn.assert_called_once_with(0)
    write_chunk_fn.assert_called_once_with(0, inventory)
    stop_fn.assert_not_called()
Example #4
0
async def test_exception_when_launching_worker(monkeypatch, manager_cfg):
    """Test if exception when launching the workers is properly handled
    """
    fake_environ = {}
    monkeypatch.setattr(os, 'environ', fake_environ)

    manager = init_static_manager(manager_cfg)

    write_chunk_fn = get_async_task_mock()
    launch_res = asyncio.Future()
    launch_res.set_exception(Exception('test'))
    launch_fn = MagicMock(return_value=launch_res)

    _, _, chunk1 = get_random_node_list(1)

    with pytest.raises(Exception, match=r'test'):
        with patch.multiple(StaticManager,
                            _launch_poller=launch_fn,
                            _write_chunk=write_chunk_fn):
            await manager.apply([chunk1])
Example #5
0
async def test_write_chunk(monkeypatch, manager_cfg):
    """Test the creation of the inventory files
    """
    fake_environ = {}
    monkeypatch.setattr(os, 'environ', fake_environ)

    devices, credentials, chunk1 = get_random_node_list(20)
    manager = init_static_manager(manager_cfg)

    # Write the chunks
    await manager._write_chunk(0, chunk1)

    # Check if something have been written
    inventory_dir = manager._inventory_path
    inventory_path = inventory_dir / f'{manager._inventory_file_name}_0.yml'
    credentials_path = inventory_dir / 'cred_0'

    # Check if files have been created
    assert inventory_path.exists(), "Inventory file not created"
    assert credentials_path.exists(), "Credentials file not created"

    # Read the file content
    # Assert the devices list is the expected one
    with open(str(inventory_path), "r") as out_file:
        inventory_data = out_file.read()
        obtained_inventory = yaml.safe_load(inventory_data)

    assert obtained_inventory == devices, \
           'Device part of the inventory do not match'

    # Assert the credentials are the expexted ones
    with open(credentials_path, "r") as out_file:
        cred_enc_data = out_file.read()

    cred_key = fake_environ['SQ_CONTROLLER_POLLER_CRED'].encode('utf-8')
    decryptor = Fernet(cred_key)
    # Decrypt the credentials
    cred_data = decryptor.decrypt(cred_enc_data.encode('utf-8'))
    obtained_credentials = yaml.safe_load(cred_data)
    assert obtained_credentials == credentials, \
           'Credentials part of the inventory do not match'
Example #6
0
async def test_inventory_changes_apply(monkeypatch, manager_cfg):
    """Check if the inventory is correctly applied
    """
    fake_environ = {}
    monkeypatch.setattr(os, 'environ', fake_environ)

    manager_args = MANAGER_ARGS.copy()
    manager_args['workers'] = 3
    manager = init_static_manager(manager_cfg, manager_args)

    _, _, chunk1 = get_random_node_list(20)
    _, _, chunk2 = get_random_node_list(20)
    _, _, chunk3 = get_random_node_list(20)

    inventory = [chunk1, chunk2, chunk3]
    launch_fn, stop_fn, \
        write_chunk_fn = await apply_with_mocks(manager, inventory)

    # Check if poller have been correctly called
    for i, c in enumerate(inventory):
        launch_fn.assert_any_call(i)
        write_chunk_fn.assert_any_call(i, c)
    stop_fn.assert_not_called()

    # Test no changes
    inventory = [chunk1, chunk2, chunk3]
    launch_fn, stop_fn, \
        write_chunk_fn = await apply_with_mocks(manager, inventory)
    launch_fn.assert_not_called()
    stop_fn.assert_not_called()
    write_chunk_fn.assert_not_called()

    # Completely change last two chunks
    _, _, chunk2 = get_random_node_list(20)
    _, _, chunk3 = get_random_node_list(20)
    inventory = [chunk1, chunk2, chunk3]
    launch_fn, stop_fn, \
        write_chunk_fn = await apply_with_mocks(manager, inventory)

    for i in range(1, 2):
        launch_fn.assert_any_call(i)
        stop_fn.assert_any_call(i)
        write_chunk_fn.assert_any_call(i, inventory[i])

    # Minor changes to one chunk
    to_change_key = list(chunk2.keys())[0]
    chunk2[to_change_key]['address'] = '10.0.0.1'
    inventory = [chunk1, chunk2, chunk3]
    launch_fn, stop_fn, \
        write_chunk_fn = await apply_with_mocks(manager, inventory)

    launch_fn.assert_any_call(1)
    stop_fn.assert_any_call(1)
    write_chunk_fn.assert_any_call(1, inventory[1])

    # All chunks change
    _, _, chunk1 = get_random_node_list(20)
    _, _, chunk2 = get_random_node_list(20)
    _, _, chunk3 = get_random_node_list(20)

    inventory = [chunk1, chunk2, chunk3]
    launch_fn, stop_fn, \
        write_chunk_fn = await apply_with_mocks(manager, inventory)

    for i, c in enumerate(inventory):
        launch_fn.assert_any_call(i)
        stop_fn.assert_any_call(i)
        write_chunk_fn.assert_any_call(i, c)