Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --json tests for repo and advisory list commands #1532

Merged
merged 4 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 199 additions & 0 deletions dnf-behave-tests/dnf/repo-json.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
@dnf5
Feature: Repo command with --json option


Background: Using repositories dnf-ci-fedora and dnf-ci-thirdparty-updates
Given I use repository "dnf-ci-fedora"
And I use repository "dnf-ci-thirdparty-updates"
And I use repository "dnf-ci-fedora-updates" with configuration
| key | value |
| enabled | 0 |
And I use repository "dnf-ci-thirdparty" with configuration
| key | value |
| enabled | 0 |


Scenario: Repo info without arguments --json
When I execute dnf with args "repo info --json"
Then the exit code is 0
And stdout json matches
"""
[
{
"id":"dnf-ci-fedora",
"name":"dnf-ci-fedora test repository",
"is_enabled":true,
"priority":99,
"cost":1000,
"type":"available",
"exclude_pkgs":[],
"include_pkgs":[],
"timestamp":"*",
"metadata_expire":172800,
"skip_if_unavailable":false,
"repo_file_path":"\/tmp\/dnf_ci_installroot_*\/etc\/yum.repos.d\/dnf-ci-fedora.repo",
"base_url":[
"file:\/\/\/*\/dnf-behave-tests\/fixtures\/repos\/dnf-ci-fedora"
],
"metalink":"",
"mirrorlist":"",
"gpg_key":[],
"repo_gpgcheck":false,
"gpgcheck":false,
"available_pkgs":289,
"pkgs":289,
"size":"*",
"content_tags":[],
"distro_tags":[],
"revision":"1550000000",
"max_timestamp":"*"
},
{
"id":"dnf-ci-thirdparty-updates",
"name":"dnf-ci-thirdparty-updates test repository",
"is_enabled":true,
"priority":99,
"cost":1000,
"type":"available",
"exclude_pkgs":[],
"include_pkgs":[],
"timestamp":"*",
"metadata_expire":172800,
"skip_if_unavailable":false,
"repo_file_path":"\/tmp\/dnf_ci_installroot_*\/etc\/yum.repos.d\/dnf-ci-thirdparty-updates.repo",
"base_url":[
"file:\/\/\/*\/dnf-behave-tests\/fixtures\/repos\/dnf-ci-thirdparty-updates"
],
"metalink":"",
"mirrorlist":"",
"gpg_key":[],
"repo_gpgcheck":false,
"gpgcheck":false,
"available_pkgs":6,
"pkgs":6,
"size":"*",
"content_tags":[],
"distro_tags":[],
"revision":"1550000000",
"max_timestamp":"*"
}
]
"""


Scenario: Repo list without arguments --json
When I execute dnf with args "repo list --json"
Then the exit code is 0
And stdout json matches
"""
[
{
"id":"dnf-ci-fedora",
"name":"dnf-ci-fedora test repository",
"is_enabled":true
},
{
"id":"dnf-ci-thirdparty-updates",
"name":"dnf-ci-thirdparty-updates test repository",
"is_enabled":true
}
]
"""


Scenario: Repo list without arguments --json --all
When I execute dnf with args "repo list --json --all"
Then the exit code is 0
And stdout json matches
"""
[
{
"id":"dnf-ci-fedora-updates",
"name":"dnf-ci-fedora-updates test repository",
"is_enabled":false
},
{
"id":"dnf-ci-fedora",
"name":"dnf-ci-fedora test repository",
"is_enabled":true
},
{
"id":"dnf-ci-thirdparty-updates",
"name":"dnf-ci-thirdparty-updates test repository",
"is_enabled":true
},
{
"id":"dnf-ci-thirdparty",
"name":"dnf-ci-thirdparty test repository",
"is_enabled":false
}
]
"""


Scenario: Repo info --json doesn't print REPOSYNC to stdout
When I execute dnf with args "repo info --json --refresh"
Then the exit code is 0
And stdout json matches
"""
[
{
"id":"dnf-ci-fedora",
"name":"dnf-ci-fedora test repository",
"is_enabled":true,
"priority":99,
"cost":1000,
"type":"available",
"exclude_pkgs":[],
"include_pkgs":[],
"timestamp":"*",
"metadata_expire":172800,
"skip_if_unavailable":false,
"repo_file_path":"\/tmp\/dnf_ci_installroot_*\/etc\/yum.repos.d\/dnf-ci-fedora.repo",
"base_url":[
"file:\/\/\/*\/dnf-behave-tests\/fixtures\/repos\/dnf-ci-fedora"
],
"metalink":"",
"mirrorlist":"",
"gpg_key":[],
"repo_gpgcheck":false,
"gpgcheck":false,
"available_pkgs":289,
"pkgs":289,
"size":"*",
"content_tags":[],
"distro_tags":[],
"revision":"1550000000",
"max_timestamp":"*"
},
{
"id":"dnf-ci-thirdparty-updates",
"name":"dnf-ci-thirdparty-updates test repository",
"is_enabled":true,
"priority":99,
"cost":1000,
"type":"available",
"exclude_pkgs":[],
"include_pkgs":[],
"timestamp":"*",
"metadata_expire":172800,
"skip_if_unavailable":false,
"repo_file_path":"\/tmp\/dnf_ci_installroot_*\/etc\/yum.repos.d\/dnf-ci-thirdparty-updates.repo",
"base_url":[
"file:\/\/\/*\/dnf-behave-tests\/fixtures\/repos\/dnf-ci-thirdparty-updates"
],
"metalink":"",
"mirrorlist":"",
"gpg_key":[],
"repo_gpgcheck":false,
"gpgcheck":false,
"available_pkgs":6,
"pkgs":6,
"size":"*",
"content_tags":[],
"distro_tags":[],
"revision":"1550000000",
"max_timestamp":"*"
}
]
"""
16 changes: 16 additions & 0 deletions dnf-behave-tests/dnf/steps/cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
import sys
import time
from datetime import datetime
import json

from common.lib.cmd import assert_exitcode, run_in_context
from common.lib.file import prepend_installroot
from fixtures import start_server_based_on_type
from lib.rpmdb import get_rpmdb_rpms
from lib.json import diff_json_pattern_values


def get_boot_time():
Expand Down Expand Up @@ -522,3 +524,17 @@ def when_I_stop_polkitd(context):
@behave.step("I stop dnf5daemon-server")
def when_I_stop_dnf5daemon_server(context):
subprocess.call(["killall", "dnf5daemon-server"])

@behave.then("stdout json matches")
def then_json_matches(context):
"""
Compare json output from stdout with specified json.
Specified json can contain fnmatch patterns in string values.
"""
table_json = json.loads(context.text)
out_json = json.loads(context.cmd_stdout)
diffs = diff_json_pattern_values(".", table_json, out_json)
if diffs:
for diff in diffs:
print(diff)
raise AssertionError("Expected JSON doesn't match")
69 changes: 69 additions & 0 deletions dnf-behave-tests/dnf/steps/lib/json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-

from __future__ import absolute_import
from __future__ import print_function

from behave.formatter.ansi_escapes import escapes
import fnmatch

def diff_recursive(parent, obj1, obj2):
problems = []
if isinstance(obj1, list) and isinstance(obj2, list):
# The list was originally a dictionary
if (len(obj1) != 0 and isinstance(obj1[0], tuple)) or len(obj2) != 0 and isinstance(obj2[0], tuple):
keys1 = next(zip(*obj1)) if len(obj1) != 0 else []
keys2 = next(zip(*obj2)) if len(obj2) != 0 else []
if keys1 != keys2:
return ["Different keys in %s object: expected: %s%s%s vs actual: %s%s%s"
% (parent, escapes['passed_arg'], keys1, escapes['reset'], escapes['failed_arg'], keys2,
escapes['reset'])]
for i in range(0, len(keys1)):
problems += diff_recursive(parent + "[" + keys1[i] + "]", obj1[i][1], obj2[i][1])
return problems

if len(obj1) != len(obj2):
return ["Different count of elements in %s array: Expected: %s%s%s vs Actual: %s%s%s"
% (parent, escapes['passed_arg'], len(obj1), escapes['reset'], escapes['failed_arg'], len(obj2),
escapes['reset'])]
for i in range(0, len(obj1)):
problems += diff_recursive(parent + "[" + str(i) + "]", obj1[i], obj2[i])
return problems

else:
# The pattern is the second argument of fnmatch
if not fnmatch.fnmatch(str(obj2), str(obj1)):
return ["Different values for %s: Expected: '%s%s%s' vs Actual: '%s%s%s'"
% (parent, escapes['passed_arg'], obj1, escapes['reset'], escapes['failed_arg'],
obj2, escapes['reset'])]
return problems


def diff_json_pattern_values(parent, obj1, obj2):
"""
Recursively compare json objects obj1 and obj2
String values of obj1 can contain fnmatch patterns

Returns a list with problems
"""

# Recursively sort lists
# (and convert dictionaries to lists of (key, value) pairs so that they're orderable)
def ordered(obj):
if isinstance(obj, list):
return sorted(ordered(x) for x in obj)
if isinstance(obj, dict):
return sorted((k, ordered(v)) for k, v in obj.items())
else:
return obj

try:
obj1 = ordered(obj1)
except TypeError:
raise AssertionError("Cannot sort expected json, this could be caused by different types in an array.")

try:
obj2 = ordered(obj2)
except TypeError:
raise AssertionError("Cannot sort input json, this could be caused by different types in an array.")

return diff_recursive(parent, obj1, obj2)
Loading
Loading