summaryrefslogtreecommitdiff
path: root/share/python/template/scenarios.py
blob: a6aa9f4aaacbd40be9dd36f15efbe21c83875e7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import logging
import os
import tempfile


#############################################################################
# Code to implement the scenarios.


class Step:
    def __init__(self):
        self._kind = None
        self._text = None
        self._args = {}
        self._function = None
        self._cleanup = None

    def set_kind(self, kind):
        self._kind = kind

    def set_text(self, text):
        self._text = text

    def set_arg(self, name, value):
        self._args[name] = value

    def set_function(self, function):
        self._function = function

    def set_cleanup(self, cleanup):
        self._cleanup = cleanup

    def do(self, ctx):
        print("  step: {} {}".format(self._kind, self._text))
        logging.info("step: {} {}".format(self._kind, self._text))
        self._function(ctx, **self._args)

    def cleanup(self, ctx):
        if self._cleanup:
            print("  cleanup: {} {}".format(self._kind, self._text))
            logging.info("cleanup: {} {}".format(self._kind, self._text))
            self._cleanup(ctx, **self._args)


_logged_env = False


class Scenario:
    def __init__(self, ctx):
        self._title = None
        self._steps = []
        self._ctx = ctx

    def get_title(self):
        return self._title

    def set_title(self, title):
        self._title = title

    def append_step(self, step):
        self._steps.append(step)

    def run(self, datadir, extra_env):
        print("scenario: {}".format(self._title))
        logging.info("Scenario: {}".format(self._title))

        scendir = tempfile.mkdtemp(dir=datadir)
        os.chdir(scendir)
        self._set_environment_variables_to(scendir, extra_env)

        done = []
        ctx = self._ctx
        try:
            for step in self._steps:
                step.do(ctx)
                done.append(step)
        except Exception as e:
            logging.error(str(e), exc_info=True)
            for step in reversed(done):
                step.cleanup(ctx)
            raise
        for step in reversed(done):
            step.cleanup(ctx)

    def _set_environment_variables_to(self, scendir, extra_env):
        log_value = globals()["log_value"]

        overrides = {
            "SHELL": "/bin/sh",
            "HOME": scendir,
            "TMPDIR": scendir,
        }

        os.environ.update(overrides)
        os.environ.update(extra_env)
        global _logged_env
        if not _logged_env:
            _logged_env = True
            log_value("extra_env", 0, dict(extra_env))
            log_value("overrides", 0, dict(overrides))
            log_value("os.environ", 0, dict(os.environ))