OStree compose requests need special options, like the `ref` the
`parent` and the `url`. Add support for those options to all three
plugins:
The command line plugin now takes `--ostree-{parent,ref,url}`
and passes it to koji via the existing options dictionary.
The JSON schemata in the hub plugin was adjusted to allow these
new options.
Finally the builder plugin will look for the new `ostree` dict
inside the options, create an `OSTreeOptions` object from it,
and attach it to each image request.
NB: since the ostree options are per image request and are thus
architecture dependent we support a "$arch" substition in the
`parent` and `ref` options that will be resolved by the plugin;
this allows to builds arch specific commits for with a single
compose request.
Add the respective unit tests.
220 lines
6.6 KiB
Python
220 lines
6.6 KiB
Python
#
|
|
# koji command line interface plugin unit tests
|
|
#
|
|
|
|
|
|
import contextlib
|
|
import io
|
|
import koji
|
|
import koji_cli.lib as kl
|
|
from flexmock import flexmock
|
|
|
|
from plugintest import PluginTest
|
|
|
|
|
|
@PluginTest.load_plugin("cli")
|
|
class TestCliPlugin(PluginTest):
|
|
|
|
@staticmethod
|
|
def mock_koji_lib(*, bg=False, task_result=0):
|
|
kojilib = flexmock(OptionParser=kl.OptionParser)
|
|
|
|
kojilib.should_receive("get_usage_str").and_return("usage")
|
|
kojilib.should_receive("activate_session").once()
|
|
kojilib.should_receive("_running_in_bg").and_return(bg)
|
|
kojilib.should_receive("watch_tasks").and_return(task_result)
|
|
|
|
return kojilib
|
|
|
|
@staticmethod
|
|
def mock_options(*, quiet=False):
|
|
options = flexmock(
|
|
quiet=quiet,
|
|
weburl="http://osbuild.org/"
|
|
)
|
|
return options
|
|
|
|
|
|
@staticmethod
|
|
def mock_session_add_valid_tag(session):
|
|
build_target = {
|
|
"build_tag": 23,
|
|
"build_tag_name": "target-build",
|
|
"dest_tag": 42,
|
|
"dest_tag_name": "target-dest"
|
|
}
|
|
|
|
tag_info = {
|
|
"id": build_target["dest_tag"],
|
|
"name": build_target["dest_tag_name"],
|
|
"locked": False
|
|
}
|
|
|
|
session.should_receive("getBuildTarget") \
|
|
.with_args("target") \
|
|
.and_return(build_target) \
|
|
.once()
|
|
|
|
session.should_receive("getTag") \
|
|
.with_args(build_target["dest_tag"]) \
|
|
.and_return(tag_info) \
|
|
.once()
|
|
|
|
return session
|
|
|
|
def test_basic_invocation(self):
|
|
# check we get the right amount of arguments
|
|
# i.e. we are missing the architecture here
|
|
argv = ["name", "version", "distro", "target"]
|
|
|
|
f = io.StringIO()
|
|
with self.assertRaises(SystemExit) as cm, \
|
|
contextlib.redirect_stderr(f):
|
|
self.plugin.handle_osbuild_image(None, None, argv)
|
|
self.assertEqual(cm.exception.code, 2)
|
|
self.assertIn("osbuild-image", f.getvalue())
|
|
f.close()
|
|
|
|
# check one successful invocation
|
|
|
|
argv = [
|
|
# the required positional arguments
|
|
"name", "version", "distro", "target", "arch1",
|
|
# optional keyword arguments
|
|
"--repo", "https://first.repo",
|
|
"--repo", "https://second.repo",
|
|
"--release", "20200202.n2",
|
|
"--skip-tag"
|
|
]
|
|
|
|
expected_args = ["name", "version", "distro",
|
|
['guest-image'], # the default image type
|
|
"target",
|
|
['arch1']]
|
|
|
|
expected_opts = {
|
|
"release": "20200202.n2",
|
|
"repo": ["https://first.repo", "https://second.repo"],
|
|
"skip_tag": True
|
|
}
|
|
|
|
task_result = {"compose_id": "42", "build_id": 23}
|
|
task_id = 1
|
|
koji_lib = self.mock_koji_lib()
|
|
|
|
options = self.mock_options()
|
|
session = flexmock()
|
|
|
|
self.mock_session_add_valid_tag(session)
|
|
|
|
session.should_receive("osbuildImage") \
|
|
.with_args(*expected_args, opts=expected_opts) \
|
|
.and_return(task_id) \
|
|
.once()
|
|
|
|
session.should_receive("logout") \
|
|
.with_args() \
|
|
.once()
|
|
|
|
session.should_receive("getTaskResult") \
|
|
.with_args(task_id) \
|
|
.and_return(task_result) \
|
|
.once()
|
|
|
|
setattr(self.plugin, "kl", koji_lib)
|
|
r = self.plugin.handle_osbuild_image(options, session, argv)
|
|
self.assertEqual(r, 0)
|
|
|
|
def test_ostree_options(self):
|
|
# Check we properly handle ostree specific options
|
|
|
|
argv = [
|
|
# the required positional arguments
|
|
"name", "version", "distro", "target", "arch1",
|
|
# optional keyword arguments
|
|
"--repo", "https://first.repo",
|
|
"--repo", "https://second.repo",
|
|
"--release", "20200202.n2",
|
|
"--ostree-parent", "ostree/$arch/staging",
|
|
"--ostree-ref", "ostree/$arch/production",
|
|
"--ostree-url", "https://osbuild.org/repo",
|
|
]
|
|
|
|
expected_args = ["name", "version", "distro",
|
|
['guest-image'], # the default image type
|
|
"target",
|
|
['arch1']]
|
|
|
|
expected_opts = {
|
|
"release": "20200202.n2",
|
|
"repo": ["https://first.repo", "https://second.repo"],
|
|
"ostree": {
|
|
"parent": "ostree/$arch/staging",
|
|
"ref": "ostree/$arch/production",
|
|
"url": "https://osbuild.org/repo",
|
|
}
|
|
}
|
|
|
|
task_result = {"compose_id": "42", "build_id": 23}
|
|
task_id = 1
|
|
koji_lib = self.mock_koji_lib()
|
|
|
|
options = self.mock_options()
|
|
session = flexmock()
|
|
|
|
self.mock_session_add_valid_tag(session)
|
|
|
|
session.should_receive("osbuildImage") \
|
|
.with_args(*expected_args, opts=expected_opts) \
|
|
.and_return(task_id) \
|
|
.once()
|
|
|
|
session.should_receive("logout") \
|
|
.with_args() \
|
|
.once()
|
|
|
|
session.should_receive("getTaskResult") \
|
|
.with_args(task_id) \
|
|
.and_return(task_result) \
|
|
.once()
|
|
|
|
setattr(self.plugin, "kl", koji_lib)
|
|
r = self.plugin.handle_osbuild_image(options, session, argv)
|
|
self.assertEqual(r, 0)
|
|
|
|
def test_target_check(self):
|
|
# unknown build target
|
|
session = flexmock()
|
|
|
|
session.should_receive("getBuildTarget") \
|
|
.with_args("target") \
|
|
.and_return(None) \
|
|
.once()
|
|
|
|
argv = ["name", "version", "distro", "target", "arch1"]
|
|
with self.assertRaises(koji.GenericError):
|
|
self.plugin.handle_osbuild_image(None, session, argv)
|
|
|
|
# unknown destination tag
|
|
build_target = {
|
|
"build_tag": 23,
|
|
"build_tag_name": "target-build",
|
|
"dest_tag": 42,
|
|
"dest_tag_name": "target-dest" # missing!
|
|
}
|
|
|
|
session = flexmock()
|
|
|
|
session.should_receive("getBuildTarget") \
|
|
.with_args("target") \
|
|
.and_return(build_target) \
|
|
.once()
|
|
|
|
session.should_receive("getTag") \
|
|
.with_args(build_target["dest_tag"]) \
|
|
.and_return(None) \
|
|
.once()
|
|
|
|
argv = ["name", "version", "distro", "target", "arch1"]
|
|
with self.assertRaises(koji.GenericError):
|
|
self.plugin.handle_osbuild_image(None, session, argv)
|