Skip to content
This repository has been archived by the owner on Oct 13, 2023. It is now read-only.

[ART-3965] A new mechanism to detect rpm changes in stream builds #798

Merged
merged 2 commits into from
Jul 19, 2023

Conversation

vfreex
Copy link
Contributor

@vfreex vfreex commented Jul 12, 2023

Currently we use a tag based approach to detect rpm changes in stream builds. It considers a package X is outdated if a newer version Y is tagged into any of X's tags. This approach has some limitations. Especially, it can't detect rpm changes after RHEL version moves or the image moves to a different repo (see https://issues.redhat.com/browse/ART-3965 for a real problem).

I will give you an example to show how it fails to detect a change:

  • Image A enables a RHEL 8.4 repo.
  • Package foo-1.0.0-1.el8_3.x86_64.rpm is installed in image A. It has rhel-8.3.0-z tag in Brew.
  • A newer version foo-1.1.0-1.el8_4.x86_64.rpm is released and has rhel-8.4.0-z tag.
  • Doozer doesn't think foo-1.0.0-1.el8_3.x86_64.rpm is outdated because the newer version foo-1.1.0-1.el8_4.x86_64.rpm doesn't have rhel-8.3.0-z tag.

To address this limitation, a new approach is proposed to actually query the content of all enabled repos and compare the installed versions with the latest versions in repos. I will call it "content based" approach.

This content based approach has been proved in gen-payload command (invoked in build-sync job) with the merge of #764. If you look at the logs of build-sync build, you will see it shows you which images contain outdated rpms. It contains entries like:

- code: OUTDATED_RPMS_IN_STREAM_BUILD
  msg: Found outdated RPM (perl-Pod-Perldoc-3.28-396.el8) installed in openshift-enterprise-builder-container-v4.14.0-202307111728.p0.gfe78ee6.assembly.stream (x86_64) when perl-Pod-Perldoc-3.28.01-443.module+el8.6.0+13324+628a2397 was available in repo rhel-8-appstream-rpms

However, the above example is actually a false positive. It is because package perl-Pod-Perldoc-3.28-396.el8 comes from a modular repo but our code is not module-aware. A modular rpm repo provides multiple upgrade paths. We should only consider a newer version is upgradable if it belongs to the same stream. For more information about modules, see https://docs.fedoraproject.org/en-US/modularity/. That is a major reason why this new approach is adopted to scan-sources, otherwise it would constantly trigger unnecessary rebuilds!

This PR not only updates scan-sources to use the new approach, but only adds module-awareness to eliminate false positives. The new algorithm (probably oversimplified):

  1. For an image build, get all modular rpms in enabled repos.
  2. For each installed rpm, check if the rpm is contained by a module.
  3. If yes, we will consider that module stream is "enabled" for this image.
  4. For each enabled module stream, find the module with the largest version.
  5. Collect all modular rpms from those modules as collection M.
  6. Collect all non-modular rpms with the latest version as collection N. If the package name of a non-modular rpm is already included in the modular rpms collection, exclude it.
  7. For each installed rpm, check if it is a modular rpm or not. If it is modular, check if it is older than the one in collection M. Otherwise, check if it is older than the one in collection N.
  8. If it is older, we consider is it an outdated rpm.

Note:

  1. There is no Brew API or any other cheap way to precisely determine which module streams are enabled during an image build. The method used in the above algorithm is actually guess. It is not perfect, but my tests conclude it is good enough for our use cases (probably because we don't use a lot of modular rpms in our images).
  2. Some images use pins in their Dockerfiles. We should exempt them from scan-sources. The exemption can be defined in ocp-build-data image metadata. e.g.
scan_sources:
  exempted_packages:
  - openvswitch3.1
  - python3-openvswitch3.1

@vfreex vfreex force-pushed the new-outdated-rpm-detection branch from acfe933 to effa5d0 Compare July 12, 2023 09:55
@openshift-eng openshift-eng deleted a comment from openshift-bot Jul 12, 2023
@vfreex vfreex changed the title WIP [ART-3965] A new mechanism to detect rpm changes in stream builds [ART-3965] A new mechanism to detect rpm changes in stream builds Jul 12, 2023
@vfreex vfreex force-pushed the new-outdated-rpm-detection branch from effa5d0 to ea946ae Compare July 12, 2023 10:04
@openshift-eng openshift-eng deleted a comment from openshift-bot Jul 12, 2023
Copy link
Contributor

@sosiouxme sosiouxme left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lots of helpful comments in here, great. would be nice to see the comments from the PR description included in the code

could you update the validator to accept exempted_packages?

just a few nits you can likely ignore, otherwise lgtm

@@ -109,6 +110,7 @@ def add_image_meta_change(meta, rebuild_hint: RebuildHint):
oldest_image_event_ts = None
newest_image_event_ts = 0
for image_meta in runtime.image_metas():
dgk = image_meta.distgit_key
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appears nothing uses this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dkg is used in line 167 and 170 for logging but we forgot to define it within the loop.
Maybe adding this variable here is not obvious because the actual use is far away from this line.
I will remove this and open another PR for the fix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feels like there had to be an existing module that already does all this, but i haven't actually looked for one! oh, well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed there are existing modules to read the content of primary.xml.gz, but didn't find anything for modules.yaml.gz. Fortunately it is not hard to parse those content so decided to do it by myself (also as a learning experience)



class OutdatedRPMFinder:
async def find_non_latest_rpms(self, rpms_to_check: List[Dict], repodatas: List[Repodata], logger: Optional[Logger] = None) -> List[Tuple[str, str, str]]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looong method. looks like it would be easy to break up into smaller testable methods?... i mean you managed to test it anyway, just seems like it would've been cleaner broken out.

@@ -188,72 +192,26 @@ def conf_section(self, repotype, arch=ARCH_X86_64, enabled=None, section_name=No

return result

# Map arch to compatible arches
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so much being removed! 🤩

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah repoquery command needs them otherwise it will not list all supported arches. It is not needed any more since because this PR reads repodata directly.

vfreex added a commit to vfreex/ocp-build-data-validator that referenced this pull request Jul 14, 2023
vfreex added a commit to vfreex/ocp-build-data-validator that referenced this pull request Jul 14, 2023
Currently we use a tag based approach to detect rpm changes in stream builds.
It considers a package X is outdated if a newer version Y is tagged into any of X's tags.
This approach has some limitations. Especially, it can't detect rpm changes after RHEL version moves or the image moves to a different repo (see https://issues.redhat.com/browse/ART-3965 for a real problem).

I will give you an example to show how it fails to detect a change:
- Image A enables a RHEL 8.4 repo.
- Package `foo-1.0.0-1.el8_3.x86_64.rpm` is installed in image A. It has `rhel-8.3.0-z` tag in Brew.
- A newer version `foo-1.1.0-1.el8_4.x86_64.rpm` is released and has `rhel-8.4.0-z` tag.
- Doozer doesn't think `foo-1.0.0-1.el8_3.x86_64.rpm` is outdated because the newer version `foo-1.1.0-1.el8_4.x86_64.rpm` doesn't have `rhel-8.3.0-z` tag.

To address this limitation, a new approach is proposed to actually query the content of all enabled repos
and compare the installed versions with the latest versions in repos. I will call it "content based" approach.

This content based approach has been proved in `gen-payload` command (invoked in `build-sync` job) with the merge of openshift-eng#764. If you look at [the logs of build-sync build](https://saml.buildvm.hosts.prod.psi.bos.redhat.com:8888/job/aos-cd-builds/job/build%252Fbuild-sync/34458/consoleFull), you will see it shows you which images contain outdated rpms. It contains entries like:

```yaml
- code: OUTDATED_RPMS_IN_STREAM_BUILD
  msg: Found outdated RPM (perl-Pod-Perldoc-3.28-396.el8) installed in openshift-enterprise-builder-container-v4.14.0-202307111728.p0.gfe78ee6.assembly.stream (x86_64) when perl-Pod-Perldoc-3.28.01-443.module+el8.6.0+13324+628a2397 was available in repo rhel-8-appstream-rpms
```

However, the above example is actually a false positive. It is because package `perl-Pod-Perldoc-3.28-396.el8` comes from
a modular repo but our code is not module-aware. A modular rpm repo provides multiple upgrade paths. We should only consider a newer version is upgradable if it belongs to the same stream. For more information about modules, see https://docs.fedoraproject.org/en-US/modularity/. That is a major reason why this new approach is adopted to `scan-sources`, otherwise it would constantly trigger unnecessary rebuilds!

This PR not only updates `scan-sources` to use the new approach, but only adds module-awareness to eliminate false positives.
The new algorithm (probably oversimplified):

1. For an image build, get all modular rpms in enabled repos.
2. For each installed rpm, check if the rpm is contained by a module.
3. If yes, we will consider that module stream is "enabled" for this image.
4. For each enabled module stream, find the module with the largest version.
5. Collect all modular rpms from those modules as collection M.
6. Collect all non-modular rpms with the latest version as collection N. If the package name of a non-modular rpm is already included in the modular rpms collection, exclude it.
7. For each installed rpm, check if it is a modular rpm or not. If it is modular, check if it is older than the one in collection M. Otherwise, check if it is older than the one in collection N.
8. If it is older, we consider is it an outdated rpm.

Note:
1. There is no Brew API or any other cheap way to precisely determine which module streams are enabled during an image build.
The method used in the above algorithm is actually *guess*. It is not perfect, but my tests conclude it is good enough for our use cases (probably because we don't use a lot of modular rpms in our images).
2. Some images use pins in their Dockerfiles. We should exempt them from scan-sources. The exemption can be defined in ocp-build-data image metadata. e.g.

```yaml
scan_sources:
  exempted_packages:
  - openvswitch3.1
  - python3-openvswitch3.1
```
@vfreex vfreex force-pushed the new-outdated-rpm-detection branch from ea946ae to 17cc8b6 Compare July 14, 2023 07:36
@openshift-eng openshift-eng deleted a comment from openshift-bot Jul 14, 2023
@openshift-eng openshift-eng deleted a comment from openshift-bot Jul 14, 2023
@openshift-bot
Copy link

Build #7

GLOB sdist-make: /mnt/workspace/jenkins/working/art-tools_doozer_PR-798/setup.py
py38 recreate: /mnt/workspace/jenkins/working/art-tools_doozer_PR-798/.tox/py38
py38 installdeps: -rrequirements-dev.txt, -rrequirements.txt
py38 inst: /mnt/workspace/jenkins/working/art-tools_doozer_PR-798/.tox/.tmp/package/1/rh-doozer-2.1.1.dev47+gf39da51.zip
py38 installed: aiofiles==23.1.0,aiohttp==3.8.4,aiosignal==1.3.1,astroid==2.15.6,async-timeout==4.0.2,attrs==23.1.0,autopep8==2.0.2,bashlex==0.18,bcrypt==4.0.1,cachetools==5.3.1,certifi==2023.5.7,cffi==1.15.1,chardet==5.1.0,charset-normalizer==3.2.0,click==8.1.5,colorama==0.4.6,coverage==7.2.7,cryptography==41.0.2,decorator==5.1.1,defusedxml==0.7.1,Deprecated==1.2.14,dill==0.3.6,distlib==0.3.6,dockerfile-parse==2.0.0,exceptiongroup==1.1.2,fastcore==1.5.29,filelock==3.12.2,flake8==6.0.0,flexmock==0.11.3,frozenlist==1.4.0,future==0.18.3,ghapi==1.0.4,gssapi==1.8.2,idna==3.4,iniconfig==2.0.0,isort==5.12.0,jira==3.4.1,koji==1.33.1,krb5==0.5.0,lazy-object-proxy==1.9.0,mccabe==0.7.0,multidict==6.0.4,mysql-connector-python==8.0.33,oauthlib==3.2.2,openshift-client==1.0.19,packaging==23.1,paramiko==3.2.0,platformdirs==3.8.1,pluggy==1.2.0,protobuf==3.20.3,pycodestyle==2.10.0,pycparser==2.21,pydantic==1.10.11,pyflakes==3.0.1,pygit2==1.10.1,PyGithub==1.59.0,PyJWT==2.7.0,pylint==2.17.4,PyNaCl==1.5.0,pyproject-api==1.5.3,pyspnego==0.9.1,pytest==7.4.0,python-dateutil==2.8.2,PyYAML==6.0,requests==2.31.0,requests-gssapi==1.2.3,requests-kerberos==0.14.0,requests-oauthlib==1.3.1,requests-toolbelt==1.0.0,rh-doozer @ file:///mnt/workspace/jenkins/working/art-tools_doozer_PR-798/.tox/.tmp/package/1/rh-doozer-2.1.1.dev47%2Bgf39da51.zip,ruamel.yaml==0.17.32,ruamel.yaml.clib==0.2.7,semver==3.0.1,setuptools-scm==7.1.0,six==1.16.0,tenacity==8.2.2,tomli==2.0.1,tomlkit==0.11.8,tox==4.6.4,typing==3.7.4.3,typing-extensions==4.7.1,urllib3==2.0.3,virtualenv==20.23.1,wrapt==1.15.0,yarl==1.9.2
py38 run-test-pre: PYTHONHASHSEED='2576246594'
py38 run-test: commands[0] | coverage run --branch --source doozerlib -m unittest discover -t . -s tests/
................................................................................................................................................s.s....................................s.s...s.s...s..s.s.s....................................../mnt/workspace/jenkins/working/art-tools_doozer_PR-798/doozerlib/repodata.py:175: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited
Coroutine created at (most recent call last)
  File "/usr/lib64/python3.8/asyncio/base_events.py", line 603, in run_until_complete
    self.run_forever()
  File "/usr/lib64/python3.8/asyncio/base_events.py", line 570, in run_forever
    self._run_once()
  File "/usr/lib64/python3.8/asyncio/base_events.py", line 1851, in _run_once
    handle._run()
  File "/usr/lib64/python3.8/asyncio/events.py", line 81, in _run
    self._context.run(self._callback, *self._args)
  File "/usr/lib64/python3.8/unittest/async_case.py", line 102, in _asyncioLoopRunner
    ret = await awaitable
  File "/usr/lib64/python3.8/unittest/mock.py", line 1342, in patched
    return await func(*newargs, **newkeywargs)
  File "/mnt/workspace/jenkins/working/art-tools_doozer_PR-798/tests/test_repodata.py", line 214, in test_load
    repodata = await loader.load(repo_name, repo_url)
  File "/mnt/workspace/jenkins/working/art-tools_doozer_PR-798/doozerlib/repodata.py", line 175, in load
    resp.raise_for_status()
  File "/usr/lib64/python3.8/unittest/mock.py", line 1081, in __call__
    return self._mock_call(*args, **kwargs)
  File "/usr/lib64/python3.8/unittest/mock.py", line 1085, in _mock_call
    return self._execute_mock_call(*args, **kwargs)
  resp.raise_for_status()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
......................................................
----------------------------------------------------------------------
Ran 285 tests in 2.309s

OK (skipped=10)
py38 run-test: commands[1] | flake8
py38 run-test: commands[2] | coverage report
Name                                          Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------------------------
doozerlib/__init__.py                            12      7      2      1    43%
doozerlib/_version.py                             2      2      0      0     0%
doozerlib/assembly.py                           158     20     87     11    84%
doozerlib/assembly_inspector.py                 220    158    128      8    24%
doozerlib/assertion.py                           13      0      6      0   100%
doozerlib/brew.py                               366    206    152      4    40%
doozerlib/build_status_detector.py               85     10     54      3    86%
doozerlib/cli/__init__.py                       122     64     28      0    39%
doozerlib/cli/__main__.py                      1203   1203    474      0     0%
doozerlib/cli/cli_opts.py                        20      3      8      0    89%
doozerlib/cli/config_plashet.py                 536    536    246      0     0%
doozerlib/cli/config_tag_rpms.py                141     20     77     15    82%
doozerlib/cli/detect_embargo.py                 167     35     70      8    75%
doozerlib/cli/get_nightlies.py                  230     59    127      3    71%
doozerlib/cli/images_health.py                   82     30     26      2    59%
doozerlib/cli/images_streams.py                 687    687    296      0     0%
doozerlib/cli/inspect_stream.py                  66     66     28      0     0%
doozerlib/cli/release_calc_upgrade_tests.py      24     24      6      0     0%
doozerlib/cli/release_gen_assembly.py           280    146    120      3    43%
doozerlib/cli/release_gen_payload.py            703    260    300     20    58%
doozerlib/cli/rpms_build.py                     165     59     58      8    57%
doozerlib/cli/rpms_read_config.py                15     15      2      0     0%
doozerlib/cli/scan_sources.py                   185    143    100      2    17%
doozerlib/comment_on_pr.py                       46      0      8      0   100%
doozerlib/config.py                              97     97     44      0     0%
doozerlib/constants.py                           12      0      0      0   100%
doozerlib/coverity.py                           255    225     82      0     9%
doozerlib/dblib.py                              263    160     68      4    35%
doozerlib/distgit.py                           1454    901    690     40    36%
doozerlib/dotconfig.py                           54     43     31      0    13%
doozerlib/exceptions.py                          14      5      0      0    64%
doozerlib/exectools.py                          226    110     80     10    48%
doozerlib/gitdata.py                            171    137     76      0    14%
doozerlib/image.py                              491    303    198      8    33%
doozerlib/logutil.py                              9      0      2      1    91%
doozerlib/metadata.py                           432    151    184     30    61%
doozerlib/model.py                              113     21     36      2    82%
doozerlib/olm/__init__.py                         0      0      0      0   100%
doozerlib/olm/bundle.py                         315    230     72      0    22%
doozerlib/osbs2_builder.py                      119     30     44     19    67%
doozerlib/plashet.py                            134      9     90     15    89%
doozerlib/pushd.py                               22      0      2      0   100%
doozerlib/release_schedule.py                    28     17      8      0    31%
doozerlib/repodata.py                           202     19     84     10    89%
doozerlib/repos.py                              239    110    123     18    48%
doozerlib/rhcos.py                              233     25     84     13    87%
doozerlib/rpm_builder.py                        232     32    123     32    80%
doozerlib/rpm_delivery.py                        16      1      0      0    94%
doozerlib/rpm_utils.py                          143     31     90      9    79%
doozerlib/rpmcfg.py                             151     61     64      8    55%
doozerlib/runtime.py                            907    690    374      7    18%
doozerlib/source_modifications.py               116     33     26      4    68%
doozerlib/state.py                               23     12      8      0    35%
doozerlib/util.py                               452    217    180     13    48%
-------------------------------------------------------------------------------
TOTAL                                         12451   7423   5266    331    37%
___________________________________ summary ____________________________________
  py38: commands succeeded
  congratulations :)

@openshift-eng openshift-eng deleted a comment from openshift-bot Jul 14, 2023
@vfreex
Copy link
Contributor Author

vfreex commented Jul 14, 2023

@sosiouxme Thank you so much for the review! I've addressed your review suggestions in the latest commit.

@openshift-eng openshift-eng deleted a comment from openshift-bot Jul 14, 2023
@openshift-bot
Copy link

Build #8

GLOB sdist-make: /mnt/workspace/jenkins/working/art-tools_doozer_PR-798/setup.py
py38 recreate: /mnt/workspace/jenkins/working/art-tools_doozer_PR-798/.tox/py38
py38 installdeps: -rrequirements-dev.txt, -rrequirements.txt
py38 inst: /mnt/workspace/jenkins/working/art-tools_doozer_PR-798/.tox/.tmp/package/1/rh-doozer-2.1.1.dev48+g2911a0a.zip
py38 installed: aiofiles==23.1.0,aiohttp==3.8.4,aiosignal==1.3.1,astroid==2.15.6,async-timeout==4.0.2,attrs==23.1.0,autopep8==2.0.2,bashlex==0.18,bcrypt==4.0.1,cachetools==5.3.1,certifi==2023.5.7,cffi==1.15.1,chardet==5.1.0,charset-normalizer==3.2.0,click==8.1.5,colorama==0.4.6,coverage==7.2.7,cryptography==41.0.2,decorator==5.1.1,defusedxml==0.7.1,Deprecated==1.2.14,dill==0.3.6,distlib==0.3.6,dockerfile-parse==2.0.0,exceptiongroup==1.1.2,fastcore==1.5.29,filelock==3.12.2,flake8==6.0.0,flexmock==0.11.3,frozenlist==1.4.0,future==0.18.3,ghapi==1.0.4,gssapi==1.8.2,idna==3.4,iniconfig==2.0.0,isort==5.12.0,jira==3.4.1,koji==1.33.1,krb5==0.5.0,lazy-object-proxy==1.9.0,mccabe==0.7.0,multidict==6.0.4,mysql-connector-python==8.0.33,oauthlib==3.2.2,openshift-client==1.0.19,packaging==23.1,paramiko==3.2.0,platformdirs==3.8.1,pluggy==1.2.0,protobuf==3.20.3,pycodestyle==2.10.0,pycparser==2.21,pydantic==1.10.11,pyflakes==3.0.1,pygit2==1.10.1,PyGithub==1.59.0,PyJWT==2.7.0,pylint==2.17.4,PyNaCl==1.5.0,pyproject-api==1.5.3,pyspnego==0.9.1,pytest==7.4.0,python-dateutil==2.8.2,PyYAML==6.0,requests==2.31.0,requests-gssapi==1.2.3,requests-kerberos==0.14.0,requests-oauthlib==1.3.1,requests-toolbelt==1.0.0,rh-doozer @ file:///mnt/workspace/jenkins/working/art-tools_doozer_PR-798/.tox/.tmp/package/1/rh-doozer-2.1.1.dev48%2Bg2911a0a.zip,ruamel.yaml==0.17.32,ruamel.yaml.clib==0.2.7,semver==3.0.1,setuptools-scm==7.1.0,six==1.16.0,tenacity==8.2.2,tomli==2.0.1,tomlkit==0.11.8,tox==4.6.4,typing==3.7.4.3,typing-extensions==4.7.1,urllib3==2.0.3,virtualenv==20.23.1,wrapt==1.15.0,yarl==1.9.2
py38 run-test-pre: PYTHONHASHSEED='2175332538'
py38 run-test: commands[0] | coverage run --branch --source doozerlib -m unittest discover -t . -s tests/
................................................................................................................................................s.s....................................s.s...s.s...s..s.s.s....................................../mnt/workspace/jenkins/working/art-tools_doozer_PR-798/doozerlib/repodata.py:175: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited
Coroutine created at (most recent call last)
  File "/usr/lib64/python3.8/asyncio/base_events.py", line 603, in run_until_complete
    self.run_forever()
  File "/usr/lib64/python3.8/asyncio/base_events.py", line 570, in run_forever
    self._run_once()
  File "/usr/lib64/python3.8/asyncio/base_events.py", line 1851, in _run_once
    handle._run()
  File "/usr/lib64/python3.8/asyncio/events.py", line 81, in _run
    self._context.run(self._callback, *self._args)
  File "/usr/lib64/python3.8/unittest/async_case.py", line 102, in _asyncioLoopRunner
    ret = await awaitable
  File "/usr/lib64/python3.8/unittest/mock.py", line 1342, in patched
    return await func(*newargs, **newkeywargs)
  File "/mnt/workspace/jenkins/working/art-tools_doozer_PR-798/tests/test_repodata.py", line 214, in test_load
    repodata = await loader.load(repo_name, repo_url)
  File "/mnt/workspace/jenkins/working/art-tools_doozer_PR-798/doozerlib/repodata.py", line 175, in load
    resp.raise_for_status()
  File "/usr/lib64/python3.8/unittest/mock.py", line 1081, in __call__
    return self._mock_call(*args, **kwargs)
  File "/usr/lib64/python3.8/unittest/mock.py", line 1085, in _mock_call
    return self._execute_mock_call(*args, **kwargs)
  resp.raise_for_status()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
......................................................
----------------------------------------------------------------------
Ran 285 tests in 2.314s

OK (skipped=10)
py38 run-test: commands[1] | flake8
py38 run-test: commands[2] | coverage report
Name                                          Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------------------------
doozerlib/__init__.py                            12      7      2      1    43%
doozerlib/_version.py                             2      2      0      0     0%
doozerlib/assembly.py                           158     20     87     11    84%
doozerlib/assembly_inspector.py                 220    158    128      8    24%
doozerlib/assertion.py                           13      0      6      0   100%
doozerlib/brew.py                               366    206    152      4    40%
doozerlib/build_status_detector.py               85     10     54      3    86%
doozerlib/cli/__init__.py                       122     64     28      0    39%
doozerlib/cli/__main__.py                      1203   1203    474      0     0%
doozerlib/cli/cli_opts.py                        20      3      8      0    89%
doozerlib/cli/config_plashet.py                 536    536    246      0     0%
doozerlib/cli/config_tag_rpms.py                141     20     77     15    82%
doozerlib/cli/detect_embargo.py                 167     35     70      8    75%
doozerlib/cli/get_nightlies.py                  230     59    127      3    71%
doozerlib/cli/images_health.py                   82     30     26      2    59%
doozerlib/cli/images_streams.py                 687    687    296      0     0%
doozerlib/cli/inspect_stream.py                  66     66     28      0     0%
doozerlib/cli/release_calc_upgrade_tests.py      24     24      6      0     0%
doozerlib/cli/release_gen_assembly.py           280    146    120      3    43%
doozerlib/cli/release_gen_payload.py            703    260    300     20    58%
doozerlib/cli/rpms_build.py                     165     59     58      8    57%
doozerlib/cli/rpms_read_config.py                15     15      2      0     0%
doozerlib/cli/scan_sources.py                   185    143    100      2    17%
doozerlib/comment_on_pr.py                       46      0      8      0   100%
doozerlib/config.py                              97     97     44      0     0%
doozerlib/constants.py                           12      0      0      0   100%
doozerlib/coverity.py                           255    225     82      0     9%
doozerlib/dblib.py                              263    160     68      4    35%
doozerlib/distgit.py                           1454    901    690     40    36%
doozerlib/dotconfig.py                           54     43     31      0    13%
doozerlib/exceptions.py                          14      5      0      0    64%
doozerlib/exectools.py                          226    110     80     10    48%
doozerlib/gitdata.py                            171    137     76      0    14%
doozerlib/image.py                              491    303    198      8    33%
doozerlib/logutil.py                              9      0      2      1    91%
doozerlib/metadata.py                           432    151    184     30    61%
doozerlib/model.py                              113     21     36      2    82%
doozerlib/olm/__init__.py                         0      0      0      0   100%
doozerlib/olm/bundle.py                         315    230     72      0    22%
doozerlib/osbs2_builder.py                      119     30     44     19    67%
doozerlib/plashet.py                            134      9     90     15    89%
doozerlib/pushd.py                               22      0      2      0   100%
doozerlib/release_schedule.py                    28     17      8      0    31%
doozerlib/repodata.py                           213     19     84     10    90%
doozerlib/repos.py                              239    110    123     18    48%
doozerlib/rhcos.py                              233     25     84     13    87%
doozerlib/rpm_builder.py                        232     32    123     32    80%
doozerlib/rpm_delivery.py                        16      1      0      0    94%
doozerlib/rpm_utils.py                          143     31     90      9    79%
doozerlib/rpmcfg.py                             151     61     64      8    55%
doozerlib/runtime.py                            907    690    374      7    18%
doozerlib/source_modifications.py               116     33     26      4    68%
doozerlib/state.py                               23     12      8      0    35%
doozerlib/util.py                               452    217    180     13    48%
-------------------------------------------------------------------------------
TOTAL                                         12462   7423   5266    331    37%
___________________________________ summary ____________________________________
  py38: commands succeeded
  congratulations :)

sosiouxme pushed a commit to openshift-eng/ocp-build-data-validator that referenced this pull request Jul 14, 2023
Copy link
Contributor

@sosiouxme sosiouxme left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@vfreex vfreex merged commit 7361c65 into openshift-eng:master Jul 19, 2023
2 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants