from gapic.samplegen_utils import (types, yaml)

BASE_PATH_KEY = "base_path"
DEFAULT_SAMPLE_DIR = "samples"

# The default environment for executing python samples.
# Custom environments must adhere to the following pattern:
# they must be a yaml.Map with a defined anchor_name field,
# and 'environment', 'base_path', and 'invocation' keys must be present.
# The 'invocation' key must map to an interpolable commandline
# that will invoke the given sample.
PYTHON3_ENVIRONMENT = yaml.Map(
    name="python",
    anchor_name="python",
    elements=[
        yaml.KeyVal("environment", "python"),
        yaml.KeyVal("bin", "python3"),
        yaml.KeyVal(BASE_PATH_KEY, DEFAULT_SAMPLE_DIR),
        yaml.KeyVal("invocation", "'{bin} {path} @args'"),
    ],
)


def generate(fpaths_and_samples,
             api_schema,
             *,
             environment: yaml.Map = PYTHON3_ENVIRONMENT,
             manifest_time: int = None) -> Tuple[str, yaml.Doc]:
    """Generate a samplegen manifest for use by sampletest

    Args:
def generate(fpaths_and_samples,
             api_schema,
             *,
             environment: yaml.Map = PYTHON3_ENVIRONMENT,
             manifest_time: int = None) -> Tuple[str, yaml.Doc]:
    """Generate a samplegen manifest for use by sampletest

    Args:
        fpaths_and_samples (Iterable[Tuple[str, Mapping[str, Any]]]):
                         The file paths and samples to be listed in the manifest
        api_schema (~.api.API): An API schema object.
        environment (yaml.Map): Optional custom sample execution environment.
                                Set this if the samples are being generated for
                                a custom language.
        manifest_time (int): Optional. An override for the timestamp in the name of the manifest filename.
                             Primarily used for testing.

    Returns:
        Tuple[str, yaml.Doc]: The filename of the manifest and the manifest data as a dictionary.

    Raises:
        types.InvalidSampleFpath: If any of the paths in fpaths_and_samples do not
                                  begin with the base_path from the environment.

    """
    base_path = environment.get(BASE_PATH_KEY, DEFAULT_SAMPLE_DIR)

    def transform_path(fpath):
        fpath = os.path.normpath(fpath)
        if not fpath.startswith(base_path):
            raise types.InvalidSampleFpath(
                f"Sample fpath does not start with '{base_path}': {fpath}")

        return "'{base_path}/%s'" % os.path.relpath(fpath, base_path)

    doc = yaml.Doc([
        yaml.KeyVal("type", "manifest/samples"),
        yaml.KeyVal("schema_version", "3"),
        environment,
        yaml.Collection(
            name="samples",
            elements=[
                [
                    # Mypy doesn't correctly intuit the type of the
                    # "region_tag" conditional expression.
                    yaml.Alias(environment.anchor_name or ""),
                    yaml.KeyVal("sample", sample["id"]),
                    yaml.KeyVal("path", transform_path(fpath)),
                    (
                        yaml.KeyVal("region_tag",
                                    sample["region_tag"])  # type: ignore
                        if "region_tag" in sample else yaml.Null),
                ] for fpath, sample in fpaths_and_samples
            ],
        ),
    ])

    dt = time.gmtime(manifest_time)
    manifest_fname_template = ("{api}.{version}.{language}."
                               "{year:04d}{month:02d}{day:02d}."
                               "{hour:02d}{minute:02d}{second:02d}."
                               "manifest.yaml")

    manifest_fname = manifest_fname_template.format(
        api=api_schema.naming.name,
        version=api_schema.naming.version,
        language=environment.name,
        year=dt.tm_year,
        month=dt.tm_mon,
        day=dt.tm_mday,
        hour=dt.tm_hour,
        minute=dt.tm_min,
        second=dt.tm_sec,
    )

    return manifest_fname, doc
Esempio n. 3
0
def test_generate_manifest():
    fpath_to_dummy_sample = {
        "samples/squid_fpath.py": {"id": "squid_sample"},
        "samples/clam_fpath.py": {"id": "clam_sample",
                                  "region_tag": "giant_clam_sample"},
    }

    fname, info = manifest.generate(
        fpath_to_dummy_sample.items(),
        DummyApiSchema(naming=DummyNaming(name="Mollusc", version="v1")),
        # Empirically derived number such that the
        # corresponding time_struct tests the zero
        # padding in the returned filename.
        manifest_time=4486525628
    )

    assert fname == "Mollusc.v1.python.21120304.090708.manifest.yaml"

    doc = gapic_yaml.Doc([
        gapic_yaml.KeyVal("type", "manifest/samples"),
        gapic_yaml.KeyVal("schema_version", "3"),
        gapic_yaml.Map(name="python",
                       anchor_name="python",
                       elements=[
                           gapic_yaml.KeyVal(
                               "environment", "python"),
                           gapic_yaml.KeyVal(
                               "bin", "python3"),
                           gapic_yaml.KeyVal(
                               "base_path", "samples"),
                           gapic_yaml.KeyVal(
                               "invocation", "'{bin} {path} @args'"),
                       ]),
        gapic_yaml.Collection(name="samples",
                              elements=[
                                  [
                                      gapic_yaml.Alias(
                                          "python"),
                                      gapic_yaml.KeyVal(
                                          "sample", "squid_sample"),
                                      gapic_yaml.KeyVal(
                                          "path", "'{base_path}/squid_fpath.py'"),
                                      gapic_yaml.Null,
                                  ],
                                  [
                                      gapic_yaml.Alias("python"),
                                      gapic_yaml.KeyVal(
                                          "sample", "clam_sample"),
                                      gapic_yaml.KeyVal(
                                          "path", "'{base_path}/clam_fpath.py'"),
                                      gapic_yaml.KeyVal(
                                          "region_tag", "giant_clam_sample")
                                  ],
                              ])
    ])

    assert info == doc

    expected_rendering = dedent(
        """\
        ---
        type: manifest/samples
        schema_version: 3
        python: &python
          environment: python
          bin: python3
          base_path: samples
          invocation: '{bin} {path} @args'
        samples:
        - <<: *python
          sample: squid_sample
          path: '{base_path}/squid_fpath.py'
        - <<: *python
          sample: clam_sample
          path: '{base_path}/clam_fpath.py'
          region_tag: giant_clam_sample
        """)

    rendered_yaml = doc.render()
    assert rendered_yaml == expected_rendering

    expected_parsed_manifest = {
        "type": "manifest/samples",
        "schema_version": 3,
        "python": {
            "environment": "python",
            "bin": "python3",
            "base_path": "samples",
            "invocation": "{bin} {path} @args",
        },
        "samples": [
            {
                "environment": "python",
                "bin": "python3",
                "base_path": "samples",
                "invocation": "{bin} {path} @args",
                "sample": "squid_sample",
                "path": "{base_path}/squid_fpath.py",
            },
            {
                "environment": "python",
                "bin": "python3",
                "base_path": "samples",
                "invocation": "{bin} {path} @args",
                "sample": "clam_sample",
                "path": "{base_path}/clam_fpath.py",
                "region_tag": "giant_clam_sample",
            },
        ],
    }

    parsed_manifest = yaml.safe_load(rendered_yaml)
    assert parsed_manifest == expected_parsed_manifest