Beispiel #1
0
    def build(self, update_application=False, quiet=False):
        """
        Create a virtual machine image of the configured host.

        Args:
            update_application (bool): If applicable, update the application
                definition Yaml file to use this image as host base for the
                selected provider. Warning, this will reset any yaml file
                formatting and comments.
            quiet (bool): If True, hide outputs.

        Returns:
            str: Image ID or path (Depending provider)
        """
        manifest = self._packer.build(quiet=quiet)
        image = self._packer.get_artifact(manifest)

        if update_application and self._application_yaml:
            application = Application(self._application_yaml)
            try:
                section = application['package'][self._provider]
            except KeyError:
                section = application['package'][self._provider] = dict()

            section['type'] = 'vm_image'
            section['name'] = image
            application.save()

        return image
Beispiel #2
0
def test_lint(tmpdir):
    """
    Test application definition file lint

    Args:
        tmpdir (py.path.local) tmpdir pytest fixture
    """
    from accelpy._application import Application, lint
    from accelpy.exceptions import ConfigurationException

    # Mock yaml definition file
    yml_file = tmpdir.join('application.yml')

    # Test: Load valid file
    yml_file.write("""
application:
  name: my_app
  version: 1.0.0

package:
  type: container_image
  name: my_container_image
  version: 1.0.0

  # Override of value in environment
  my_provider:
    type: vm_image
    name: my_vm_image

firewall_rules:
  - start_port: 1000
    end_port: 1000
    protocol: tcp
    direction: ingress
  - start_port: 1001
    end_port: 1100
    protocol: tcp
    direction: egress

fpga:
  # Mandatory value only in environment
  my_provider:
    image: my_fpga_image
""")
    app = Application(yml_file)

    # Test: __getitem__
    assert app['application']['name'] == 'my_app'

    # Test section _node
    assert isinstance(app['firewall_rules'], list)
    assert isinstance(app['application'], dict)

    # Test: get
    assert app.get('fpga', 'image') is None
    assert app.get('fpga', 'image', 'my_provider') == ['my_fpga_image']
    assert app.get('package', 'type') == 'container_image'
    assert app.get('package', 'type', 'my_provider') == 'vm_image'

    # Test: save
    app['package']['name'] = 'another_image'
    app.save()
    assert Application(yml_file)['package']['name'] == 'another_image'

    # Test: environment
    assert app.environments == {'my_provider'}

    # Test: Load valid file with missing not mandatory section
    yml_file.write("""
application:
  name: my_app
  version: 1.0.0

package:
  type: container_image
  name: my_container_image

fpga:
  image: image
""")
    app = Application(yml_file)
    assert app['firewall_rules'] == []

    # Test: Load bad section type
    yml_file.write("""
application:
  - name: my_app
    version: 1.0.0

package:
  type: container_image
  name: my_container_image

fpga:
  image: image
""")
    with pytest.raises(ConfigurationException):
        lint(yml_file)

    # Test: Missing mandatory value in default keys
    yml_file.write("""
application:
  name: my_app

package:
  # Missing image
  type: container_image

fpga:
  image: image
""")
    with pytest.raises(ConfigurationException):
        lint(yml_file)

    # Test: Missing mandatory value in environment keys
    yml_file.write("""
application:
  name: my_app
  version: 1.0.0

package:
  # Missing image
  my_provider:
    type: container_image

fpga:
  image: image
""")
    with pytest.raises(ConfigurationException):
        lint(yml_file)

    # Test: Value not in list
    yml_file.write("""
application:
  name: my_app
  version: 1.0.0

package:
  type: container_image
  name: my_container_image

firewall_rules:
  - start_port: 1000
    end_port: 1000
    protocol: tcp
    # No a known direction
    direction: no_direction

fpga:
  image: image
""")
    with pytest.raises(ConfigurationException):
        lint(yml_file)

    # Test: Bad value type
    yml_file.write("""
application:
  name: my_app
  version: 1.0.0

package:
  type: container_image
  name: my_container_image

fpga:
  image: image
  # Count should be an int
  count: "1"
""")
    with pytest.raises(ConfigurationException):
        lint(yml_file)

    # Test: Bad value type in list
    yml_file.write("""
application:
  name: my_app
  version: 1.0.0

package:
  type: container_image
  name: my_container_image

fpga:
  image:
    - image_slot0
    - 1
  count: 1
""")
    with pytest.raises(ConfigurationException):
        lint(yml_file)

    # Test: List of values
    yml_file.write("""
application:
  name: my_app
  version: 1.0.0

package:
  type: container_image
  name: my_container_image

fpga:
  image:
    - image_slot0
    - image_slot1
  count: 1
""")
    lint(yml_file)

    # Test: Auto list conversion
    yml_file.write("""
application:
  name: my_app
  version: 1.0.0

package:
  type: container_image
  name: my_container_image

fpga:
  image: image_slot0
  count: 1
""")
    lint(yml_file)

    # Test: top level list bad value
    yml_file.write("""
application:
  name: my_app
  version: 1.0.0

package:
  type: container_image
  name: my_container_image

fpga:
  image: 1
  count: 1
""")
    with pytest.raises(ConfigurationException):
        lint(yml_file)
def test_lint(tmpdir):
    """
    Test application definition file lint

    Args:
        tmpdir (py.path.local) tmpdir pytest fixture
    """
    from accelpy._application import Application
    from accelpy.exceptions import ConfigurationException

    # Mock yaml definition file
    yml_file = tmpdir.join('application.yml')

    # Test: Load valid file
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0

package:
  - type: container_image
    name: my_container_image
    version: 1.0.0

    # Override of value in provider
    my_provider:
      type: vm_image
      name: my_vm_image

firewall_rules:
  - start_port: 1000
    end_port: 1000
    protocol: tcp
    direction: ingress
  - start_port: 1001
    end_port: 1100
    protocol: tcp
    direction: egress

fpga:
  # Mandatory value only in provider
  my_provider:
    image: my_fpga_image
""")
    app = Application(yml_file)

    # Test section _node
    assert isinstance(app['firewall_rules'], list)
    assert isinstance(app['application'], dict)

    # Test: get
    assert app['fpga']['image'] == []
    assert app['my_provider']['fpga']['image'] == ['my_fpga_image']
    assert app['package'][0]['type'] == 'container_image'
    assert app['my_provider']['package'][0]['type'] == 'vm_image'

    # Test: save and reload
    app['package'][0]['my_provider']['name'] = 'another_image'
    app.save()
    assert Application(
        yml_file)['my_provider']['package'][0]['name'] == 'another_image'

    # Test: provider
    assert app.providers == {'my_provider'}

    # Test: Load valid file with missing not mandatory section
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0

package:
  - type: container_image
    name: my_container_image

fpga:
  image: image
""")
    app = Application(yml_file)
    assert app['firewall_rules'] == []

    # Test: Load file with inferred list section from mapping
    yml_file.write("""
    application:
      product_id: my_product_id
      version: 1.0.0

    package:
      type: container_image
      name: my_container_image

    fpga:
      image: image
    """)
    app = Application(yml_file)
    assert app['package'][0]['type'] == 'container_image'

    # Test: Provider with reserved name
    yml_file.write("""
    application:
      product_id: my_product_id
      version: 1.0.0

    package:
      - type: container_image
        name: my_container_image

    fpga:
      image: image
      application:
        image: image
    """)
    with pytest.raises(ConfigurationException):
        Application(yml_file)

    # Test: Missing or empty package section
    yml_file.write("""
    application:
      product_id: my_product_id
      version: 1.0.0

    package: []

    fpga:
      image: image
    """)
    with pytest.raises(ConfigurationException):
        Application(yml_file)

    yml_file.write("""
    application:
      product_id: my_product_id
      version: 1.0.0

    fpga:
      image: image
    """)
    with pytest.raises(ConfigurationException):
        Application(yml_file)

    # Test: Load bad section type
    yml_file.write("""
application:
  - product_id: my_product_id
    version: 1.0.0

package:
  - type: container_image
    name: my_container_image

fpga:
  image: image
""")
    with pytest.raises(ConfigurationException):
        Application(yml_file)

    # Test: Missing mandatory value in default keys
    yml_file.write("""
application:
  product_id: my_product_id

package:
  # Missing image
  - type: container_image

fpga:
  image: image
""")
    with pytest.raises(ConfigurationException):
        Application(yml_file)

    # Test: Missing mandatory value in provider keys
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0

package:
  # Missing image
  - my_provider:
      type: container_image

fpga:
  image: image
""")
    with pytest.raises(ConfigurationException):
        Application(yml_file)

    # Test: Value not in list
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0

package:
  - type: container_image
    name: my_container_image

firewall_rules:
  - start_port: 1000
    end_port: 1000
    protocol: tcp
    # No a known direction
    direction: no_direction

fpga:
  image: image
""")
    with pytest.raises(ConfigurationException):
        Application(yml_file)

    # Test: Bad value type
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0

package:
  - type: container_image
    name: my_container_image

fpga:
  image: image
  # Count should be an int
  count: "1"
""")
    with pytest.raises(ConfigurationException):
        Application(yml_file)

    # Test: Bad value type for str type
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0

package:
  - type: container_image
    name: my_container_image

fpga:
  image: image
  # Driver version should be a str
  driver_version: 1.0
    """)
    Application(yml_file)

    # Test: Bad value type in list
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0

package:
  - type: container_image
    name: my_container_image

fpga:
  image:
    - image_slot0
    - 1
  count: 1
""")
    with pytest.raises(ConfigurationException):
        Application(yml_file)

    # Test: List of values
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0

package:
  - type: container_image
    name: my_container_image

fpga:
  image:
    - image_slot0
    - image_slot1
  count: 1
""")
    Application(yml_file)

    # Test: Auto list conversion
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0

package:
  - type: container_image
    name: my_container_image

fpga:
  image: image_slot0
  count: 1
""")
    Application(yml_file)

    # Test: top level list bad value
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0

package:
  - type: container_image
    name: my_container_image

fpga:
  image: 1
  count: 1
""")
    with pytest.raises(ConfigurationException):
        Application(yml_file)

    # Test: Extra section should not raise
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0

package:
  - type: container_image
    name: my_container_image

fpga:
  image: image
  
extra_section:
  extra_key: value
""")
    with pytest.raises(ConfigurationException):
        Application(yml_file)

    # Test: Extra key should raise
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0

package:
  - type: container_image
    name: my_container_image

fpga:
  image: image
  extra_key: value
""")
    with pytest.raises(ConfigurationException):
        Application(yml_file)

    # Test: Extra key should raise in provider
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0

package:
  - type: container_image
    name: my_container_image

fpga:
  image: image
  my_provider:
    extra_key: value
""")
    with pytest.raises(ConfigurationException):
        Application(yml_file)

    # Test: Value does not match regex
    yml_file.write("""
application:
  product_id: my_product_id
  version: 1.0.0.0.0

package:
  - type: container_image
    name: my_container_image

fpga:
  image: image
""")
    with pytest.raises(ConfigurationException):
        Application(yml_file)