dv-flow-mgr 0.0.1.12932354274a1__tar.gz → 0.0.1.12941329363a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/PKG-INFO +1 -1
  2. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/pyproject.toml +1 -1
  3. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/cmds/cmd_run.py +2 -0
  4. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/pkg_rgy.py +32 -8
  5. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/task_graph_builder.py +11 -9
  6. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/task_graph_runner_local.py +6 -4
  7. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow_mgr.egg-info/PKG-INFO +1 -1
  8. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow_mgr.egg-info/SOURCES.txt +1 -0
  9. dv_flow_mgr-0.0.1.12941329363a1/tests/sys/test_pkg_discovery.py +108 -0
  10. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/.github/workflows/ci.yml +0 -0
  11. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/.gitignore +0 -0
  12. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/.vscode/settings.json +0 -0
  13. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/LICENSE +0 -0
  14. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/README.md +0 -0
  15. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/docs/Makefile +0 -0
  16. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/docs/Notes.md +0 -0
  17. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/docs/Roadmap.md +0 -0
  18. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/docs/Stages.md +0 -0
  19. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/docs/TypesAndDefs.md +0 -0
  20. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/docs/conf.py +0 -0
  21. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/docs/index.rst +0 -0
  22. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/docs/intro.rst +0 -0
  23. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/docs/quickstart.rst +0 -0
  24. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/docs/reference.rst +0 -0
  25. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/ivpm.yaml +0 -0
  26. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/setup.cfg +0 -0
  27. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/__init__.py +0 -0
  28. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/__main__.py +0 -0
  29. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/fileset.py +0 -0
  30. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/fragment_def.py +0 -0
  31. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/package.py +0 -0
  32. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/package_def.py +0 -0
  33. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/package_import_spec.py +0 -0
  34. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/share/flow.json +0 -0
  35. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/std/fileset.py +0 -0
  36. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/std/flow.dv +0 -0
  37. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/std/message.py +0 -0
  38. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/std/task_fileset.py +0 -0
  39. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/std/task_null.py +0 -0
  40. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/task.py +0 -0
  41. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/task_data.py +0 -0
  42. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/task_def.py +0 -0
  43. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/task_graph_runner.py +0 -0
  44. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/task_memento.py +0 -0
  45. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow/mgr/util.py +0 -0
  46. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow_mgr.egg-info/dependency_links.txt +0 -0
  47. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow_mgr.egg-info/entry_points.txt +0 -0
  48. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow_mgr.egg-info/requires.txt +0 -0
  49. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/src/dv_flow_mgr.egg-info/top_level.txt +0 -0
  50. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/examples/example1/example1.flow +0 -0
  51. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/__init__.py +0 -0
  52. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/data/fileset/test1/files1/file1_1.sv +0 -0
  53. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/data/fileset/test1/files1/file1_2.sv +0 -0
  54. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/data/fileset/test1/files2/file2_1.sv +0 -0
  55. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/data/fileset/test1/files2/file2_2.sv +0 -0
  56. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/data/fileset/test1/flow.dv +0 -0
  57. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/data/fileset/test1 copy/files1/file1_1.sv +0 -0
  58. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/data/fileset/test1 copy/files1/file1_2.sv +0 -0
  59. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/data/fileset/test1 copy/files2/file2_1.sv +0 -0
  60. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/data/fileset/test1 copy/files2/file2_2.sv +0 -0
  61. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/data/fileset/test1 copy/test1.dfs +0 -0
  62. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/data/proj1/proj1.dfs +0 -0
  63. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/data/proj2/proj2.dfs +0 -0
  64. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/data/proj3/proj3.dfs +0 -0
  65. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/test_data_merge.py +0 -0
  66. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/test_fileset.py +0 -0
  67. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/test_pyclass.py +0 -0
  68. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/test_smoke copy.sav +0 -0
  69. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/test_smoke.py +0 -0
  70. {dv_flow_mgr-0.0.1.12932354274a1 → dv_flow_mgr-0.0.1.12941329363a1}/tests/unit/test_stdlib.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: dv-flow-mgr
3
- Version: 0.0.1.12932354274a1
3
+ Version: 0.0.1.12941329363a1
4
4
  Summary: DV Flow Manager is a build system for silicon design
5
5
  Author-email: Matthew Ballance <matt.ballance@gmail.com>
6
6
  License: Apache License
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "dv-flow-mgr"
8
- version = "0.0.1.12932354274a1"
8
+ version = "0.0.1.12941329363a1"
9
9
  dependencies = [
10
10
  'pydantic',
11
11
  'pyyaml',
@@ -59,6 +59,8 @@ class CmdRun(object):
59
59
  tasks = []
60
60
 
61
61
  for spec in args.tasks:
62
+ if spec.find('.') == -1:
63
+ spec = pkg.name + "." + spec
62
64
  task = builder.mkTaskGraph(spec)
63
65
  tasks.append(task)
64
66
 
@@ -31,13 +31,11 @@ class PkgRgy(object):
31
31
  self._pkgpath = []
32
32
  self._pkg_m : Dict[str, Tuple[str,PackageDef]] = {}
33
33
 
34
- def hasPackage(self, name, search_path=False):
34
+ def hasPackage(self, name, search_path=True):
35
35
  if name in self._pkg_m.keys():
36
36
  return True
37
- elif search_path:
38
- for p in self._pkgpath:
39
- if os.path.exists(os.path.join(p, name)):
40
- return True
37
+ elif search_path and self._findOnPath(name) is not None:
38
+ return True
41
39
  else:
42
40
  return False
43
41
 
@@ -50,11 +48,33 @@ class PkgRgy(object):
50
48
  self._pkg_m[name][0],
51
49
  pkg_def
52
50
  )
53
- pass
54
51
  return self._pkg_m[name][1]
55
52
  else:
56
- # Go search the package path
57
- return None
53
+ return self._findOnPath(name)
54
+
55
+ def _findOnPath(self, name):
56
+ name_s = name.split('.')
57
+ name_dir = "/".join(name_s)
58
+ if len(name_s) > 1:
59
+ name_pref = "/".join(name_s[:-1])
60
+ else:
61
+ name_pref = None
62
+
63
+ pkg = None
64
+
65
+ for path in self._pkgpath:
66
+ if os.path.isfile(os.path.join(path, name_dir, "flow.dv")):
67
+ pkg = PackageDef.load(os.path.join(path, name_dir, "flow.dv"))
68
+ elif name_pref is not None and os.path.isfile(os.path.join(path, name_pref, name_s[-1] + ".dv")):
69
+ pkg = PackageDef.load(os.path.join(path, name_pref, name_s[-1] + ".dv"))
70
+ elif os.path.isfile(os.path.join(path, name + ".dv")):
71
+ pkg = PackageDef.load(os.path.join(path, name + ".dv"))
72
+
73
+ if pkg is not None:
74
+ self._pkg_m[name] = (pkg.name, pkg)
75
+ break
76
+
77
+ return pkg
58
78
 
59
79
  def registerPackage(self, pkg_def):
60
80
  if pkg_def.name in self._pkg_m.keys():
@@ -65,6 +85,10 @@ class PkgRgy(object):
65
85
  # Register built-in package
66
86
  self._pkg_m["std"] = (os.path.join(os.path.dirname(__file__), "std/flow.dv"), None)
67
87
 
88
+ if "DV_FLOW_PATH" in os.environ.keys() and os.environ["DV_FLOW_PATH"] != "":
89
+ paths = os.environ["DV_FLOW_PATH"].split(':')
90
+ self._pkgpath.extend(paths)
91
+
68
92
  if sys.version_info < (3,10):
69
93
  from importlib_metadata import entry_points
70
94
  else:
@@ -35,7 +35,6 @@ class TaskGraphBuilder(object):
35
35
  pkg_rgy : PkgRgy = None
36
36
  _pkg_s : List[Package] = dc.field(default_factory=list)
37
37
  _pkg_m : Dict[PackageSpec,Package] = dc.field(default_factory=dict)
38
- _pkg_def_m : Dict[str,PackageDef] = dc.field(default_factory=dict)
39
38
  _pkg_spec_s : List[PackageDef] = dc.field(default_factory=list)
40
39
  _task_m : Dict[TaskSpec,Task] = dc.field(default_factory=dict)
41
40
 
@@ -127,8 +126,6 @@ class TaskGraphBuilder(object):
127
126
  else:
128
127
  pkg_def = None
129
128
 
130
- print("spec: %s ; _pkg_def_m: %s" % (str(spec), str(self._pkg_def_m.keys())))
131
-
132
129
  # Need a stack to track which package we are currently in
133
130
  # Need a map to get a concrete package from a name with parameterization
134
131
 
@@ -140,8 +137,9 @@ class TaskGraphBuilder(object):
140
137
  pkg = self._pkg_s[-1]
141
138
  if spec in self._pkg_m.keys():
142
139
  pkg = self._pkg_m[spec]
143
- elif spec in self._pkg_def_m.keys():
144
- pkg = self._pkg_def_m[spec].mkPackage(self)
140
+ elif self.pkg_rgy.hasPackage(spec.name):
141
+ pkg_def = self.pkg_rgy.getPackage(spec.name)
142
+ pkg = pkg_def.mkPackage(self)
145
143
  self._pkg_m[spec] = pkg
146
144
  else:
147
145
  pkg = None
@@ -156,22 +154,26 @@ class TaskGraphBuilder(object):
156
154
  tgt_pkg_spec = PackageSpec(imp.name)
157
155
  if tgt_pkg_spec in self._pkg_m.keys():
158
156
  pkg = self._pkg_m[tgt_pkg_spec]
159
- elif tgt_pkg_spec in self._pkg_def_m.keys():
160
- base = self._pkg_def_m[tgt_pkg_spec]
157
+ elif self.pkg_rgy.hasPackage(tgt_pkg_spec.name):
158
+ base = self.pkg_rgy.getPackage(tgt_pkg_spec.name)
161
159
  pkg = base.mkPackage(self, spec.params)
162
160
  self._pkg_m[spec] = pkg
163
161
  elif imp.path is not None:
164
162
  # See if we can load the package
165
163
  print("TODO: load referenced package")
166
164
  else:
167
- raise Exception("Import alias %s not found" % imp.name)
165
+ raise Exception("Failed to resolve target (%s) of import alias %s" % (
166
+ imp.name,
167
+ imp.alias))
168
168
  break
169
169
  else:
170
170
  # Need to compare the spec with the full import spec
171
171
  imp_spec = PackageSpec(imp.name)
172
172
  # TODO: set parameters
173
173
  if imp_spec == spec:
174
- base = self._pkg_def_m[PackageSpec(spec.name)]
174
+ base = self.pkg_rgy.getPackage(spec.name)
175
+ if base is None:
176
+ raise Exception("Failed to find imported package %s" % spec.name)
175
177
  pkg = base.mkPackage(self, spec.params)
176
178
  self._pkg_m[spec] = pkg
177
179
  break
@@ -74,6 +74,8 @@ class TaskGraphRunnerLocal(TaskGraphRunner):
74
74
  print("dep_m: %s" % str(dep_m))
75
75
 
76
76
  order = list(toposort(dep_m))
77
+
78
+ print("order: %s" % str(order))
77
79
 
78
80
  active_task_l : List[Tuple[Task,Coroutine]]= []
79
81
  # Now, iterate over the concurrent sets
@@ -93,9 +95,9 @@ class TaskGraphRunnerLocal(TaskGraphRunner):
93
95
  active_task_l.pop(i)
94
96
  break
95
97
  if t not in self.done_task_m.keys():
96
- task = task_m[t]
97
- coro = asyncio.Task(task.do_run())
98
- active_task_l.append((task, coro))
98
+ task_t = task_m[t]
99
+ coro = asyncio.Task(task_t.do_run())
100
+ active_task_l.append((task_t, coro))
99
101
 
100
102
  # Now, wait for tasks to complete
101
103
  if len(active_task_l):
@@ -110,7 +112,7 @@ class TaskGraphRunnerLocal(TaskGraphRunner):
110
112
  ret = None
111
113
 
112
114
  if unwrap:
113
- return task.output
115
+ return task[0].output
114
116
  else:
115
117
  return list(t.output for t in task)
116
118
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: dv-flow-mgr
3
- Version: 0.0.1.12932354274a1
3
+ Version: 0.0.1.12941329363a1
4
4
  Summary: DV Flow Manager is a build system for silicon design
5
5
  Author-email: Matthew Ballance <matt.ballance@gmail.com>
6
6
  License: Apache License
@@ -45,6 +45,7 @@ src/dv_flow_mgr.egg-info/entry_points.txt
45
45
  src/dv_flow_mgr.egg-info/requires.txt
46
46
  src/dv_flow_mgr.egg-info/top_level.txt
47
47
  tests/examples/example1/example1.flow
48
+ tests/sys/test_pkg_discovery.py
48
49
  tests/unit/__init__.py
49
50
  tests/unit/test_data_merge.py
50
51
  tests/unit/test_fileset.py
@@ -0,0 +1,108 @@
1
+ import os
2
+ import pytest
3
+ import subprocess
4
+ import sys
5
+
6
+
7
+ def test_import_specific(tmpdir):
8
+ flow_dv = """
9
+ package:
10
+ name: p1
11
+
12
+ imports:
13
+ - name: p2
14
+
15
+ tasks:
16
+ - name: my_task
17
+ uses: p2.doit
18
+ """
19
+
20
+ p2_flow_dv = """
21
+ package:
22
+ name: p2
23
+
24
+ tasks:
25
+ - name: doit
26
+ uses: std.Message
27
+ with:
28
+ msg: "Hello There"
29
+ """
30
+
31
+ rundir = os.path.join(tmpdir)
32
+
33
+ with open(os.path.join(rundir, "flow.dv"), "w") as fp:
34
+ fp.write(flow_dv)
35
+
36
+ os.makedirs(os.path.join(rundir, "p2"))
37
+ with open(os.path.join(rundir, "p2/flow.dv"), "w") as fp:
38
+ fp.write(p2_flow_dv)
39
+
40
+ env = os.environ.copy()
41
+ env["DV_FLOW_PATH"] = rundir
42
+
43
+ cmd = [
44
+ sys.executable,
45
+ "-m",
46
+ "dv_flow.mgr",
47
+ "run",
48
+ "my_task"
49
+ ]
50
+
51
+ output = subprocess.check_output(cmd, cwd=rundir, env=env)
52
+
53
+ output = output.decode()
54
+
55
+ assert output.find("Hello There") != -1
56
+
57
+
58
+ def test_import_alias(tmpdir):
59
+ flow_dv = """
60
+ package:
61
+ name: p1
62
+
63
+ imports:
64
+ - name: p2
65
+ as: p3
66
+
67
+ tasks:
68
+ - name: my_task
69
+ uses: p3.doit
70
+ """
71
+
72
+ p2_flow_dv = """
73
+ package:
74
+ name: p2
75
+
76
+ tasks:
77
+ - name: doit
78
+ uses: std.Message
79
+ with:
80
+ msg: "Hello There"
81
+ """
82
+
83
+ rundir = os.path.join(tmpdir)
84
+
85
+ with open(os.path.join(rundir, "flow.dv"), "w") as fp:
86
+ fp.write(flow_dv)
87
+
88
+ os.makedirs(os.path.join(rundir, "p2"))
89
+ with open(os.path.join(rundir, "p2/flow.dv"), "w") as fp:
90
+ fp.write(p2_flow_dv)
91
+
92
+ env = os.environ.copy()
93
+ env["DV_FLOW_PATH"] = rundir
94
+
95
+ cmd = [
96
+ sys.executable,
97
+ "-m",
98
+ "dv_flow.mgr",
99
+ "run",
100
+ "my_task"
101
+ ]
102
+
103
+ output = subprocess.check_output(cmd, cwd=rundir, env=env)
104
+
105
+ output = output.decode()
106
+
107
+ assert output.find("Hello There") != -1
108
+