Skip to content
Snippets Groups Projects
utils.py 2.35 KiB
Newer Older
Simon Rose's avatar
Simon Rose committed
import os
import subprocess
import time
from pathlib import Path
Simon Rose's avatar
Simon Rose committed
from random import choice
from string import ascii_lowercase
Simon Rose's avatar
Simon Rose committed

Simon Rose's avatar
Simon Rose committed
import pytest
from git import Repo
from run_iocsh import IOC
Simon Rose's avatar
Simon Rose committed

Simon Rose's avatar
Simon Rose committed
# Random module name
TEST_MODULE_NAME = "test_mod_" + "".join(choice(ascii_lowercase) for _ in range(16))

Simon Rose's avatar
Simon Rose committed
EPICS_BASE = os.environ.get("EPICS_BASE")
E3_REQUIRE_VERSION = os.environ.get("E3_REQUIRE_VERSION")

CONFIG = f"""
TOP:=$(CURDIR)

# To configure require
EPICS_BASE:=$(__EPICS_BASE_LOCATION)
E3_REQUIRE_VERSION:=$(__REQUIRE_VERSION)

E3_REQUIRE_LOCATION := $(EPICS_BASE)/require/$(E3_REQUIRE_VERSION)
REQUIRE_CONFIG := $(E3_REQUIRE_LOCATION)/configure

# To configure the modules
EPICS_MODULE_NAME:={TEST_MODULE_NAME}
E3_MODULE_VERSION:=$(__DEBUG_VERSION)
E3_MODULE_NAME:=$(EPICS_MODULE_NAME)
E3_MODULE_SRC_PATH:=$(EPICS_MODULE_NAME)
E3_MODULE_MAKEFILE:=$(EPICS_MODULE_NAME).Makefile

include $(REQUIRE_CONFIG)/CONFIG
include $(REQUIRE_CONFIG)/RULES_SITEMODS
"""

MODULE_MAKEFILE = """
where_am_I := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
include $(E3_REQUIRE_TOOLS)/driver.makefile

TEMPLATES += {templates}
SOURCES += {sources}
DBDS += {dbds}
HEADERS += {headers}
"""


def run_make(path, *args, **kwargs):
    test_env = os.environ.copy()
    test_env["__EPICS_BASE_LOCATION"] = EPICS_BASE
    test_env["__REQUIRE_VERSION"] = E3_REQUIRE_VERSION
    for kw in kwargs:
        test_env[kw] = kwargs[kw]
    make_cmd = ["make", "-C", path] + list(args)
    p = subprocess.Popen(
        make_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=test_env
    )
    outs, errs = p.communicate()
    return p.returncode, outs, errs


def run_ioc_get_output(version, cell_path):
    with IOC("-r", f"{TEST_MODULE_NAME},{version}", "-l", cell_path) as ioc:
        time.sleep(1)
    return ioc.proc.returncode, ioc.outs, ioc.errs


@pytest.fixture
def wrapper(tmpdir, request):
    wrapper_dir = Path(tmpdir / "wrapper")
    test_dir = wrapper_dir / TEST_MODULE_NAME
    test_dir.mkdir(parents=True)

    # TODO: This should not be necessary, but it is for patching.
    Repo.init(wrapper_dir)
    with open(wrapper_dir / "Makefile", "w") as f:
        f.write(CONFIG)
    with open(wrapper_dir / f"{TEST_MODULE_NAME}.Makefile", "w") as f:
        f.write(MODULE_MAKEFILE.format(**request.param))
    with open(wrapper_dir / TEST_MODULE_NAME / "test.dbd", "w") as f:
        f.write("")
    yield wrapper_dir