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

Builds.get() new arg: fields #18

Merged
merged 5 commits into from
Sep 28, 2023
Merged

Conversation

GeneMyslinsky
Copy link
Contributor

I have a use case where I want to be able to see all running builds without having to iterate over by item.
Seeing the duration and status is also useful.

There are other useful fields as well which I've included in the docstring.

I didn't run the tests. Sorry.

@pbelskiy
Copy link
Owner

Hi! Thanks for PR, please fix CI errors

@GeneMyslinsky
Copy link
Contributor Author

GeneMyslinsky commented Sep 20, 2023

I did add 2 additional new optional args to specify a start and stop index, this helps for builds which have over 1000+ runs in the history.

Tox passed for me locally.
Feel free to make any changes.

from the docs:

For array-type properties, a range specifier is supported. For example, tree=jobs[name]{0,10} would retrieve the name of the first 10 jobs. The range specifier has the following variants:

{M,N}: From the M-th element (inclusive) to the N-th element (exclusive).
{M,}: From the M-th element (inclusive) to the end.
{,N}: From the first element (inclusive) to the N-th element (exclusive). The same as {0,N}.
{N}: Just retrieve the N-th element. The same as {N,N+1}. 

@GeneMyslinsky
Copy link
Contributor Author

GeneMyslinsky commented Sep 20, 2023

don't mind the function name, no way I could figure out how to make the API give me ONLY running jobs
image

Copy link
Owner

@pbelskiy pbelskiy left a comment

Choose a reason for hiding this comment

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

Please add tests for it

ujenkins/endpoints/builds.py Outdated Show resolved Hide resolved
ujenkins/endpoints/builds.py Outdated Show resolved Hide resolved
ujenkins/endpoints/builds.py Outdated Show resolved Hide resolved
ujenkins/endpoints/builds.py Outdated Show resolved Hide resolved
ujenkins/endpoints/builds.py Outdated Show resolved Hide resolved
ujenkins/endpoints/builds.py Outdated Show resolved Hide resolved
ujenkins/endpoints/builds.py Outdated Show resolved Hide resolved
@GeneMyslinsky
Copy link
Contributor Author

GeneMyslinsky commented Sep 24, 2023

@pbelskiy how do you want me to add tests for this?
Your current tests are just just mocking the response that jenkins would give back.

I could add another mock string, but why not just test if the request was formulated properly instead of a mock response?

BUILDS_ALL_JSON_SELECTIVE = """{
    "_class": "hudson.model.FreeStyleProject",
    "allBuilds": [
        {
            "_class": "hudson.model.FreeStyleBuild",
            "number": 2,
            "url": "http://localhost:8080/job/jobbb/2/"
        },
        {
            "_class": "hudson.model.FreeStyleBuild",
            "number": 3,
            "url": "http://localhost:8080/job/jobbb/3/"
        },
        {
            "_class": "hudson.model.FreeStyleBuild",
            "number": 4,
            "url": "http://localhost:8080/job/jobbb/4/"
        }
    ]
}
"""
@responses.activate
def test_get_selective(client):
    responses.add(
        responses.GET,
        re.compile(r'.*/api/json'),
        body=BUILDS_ALL_JSON_SELECTIVE,
    )
    fields = ['number', 'url']
    response = client.builds.get('job', fields=fields, start=2, end=4)
    print(response)
    assert len(response) == 3
    assert response[0]['number'] == 2

I think the real way to go forward is to spin up a docker container and execute the tests against a fresh instance.

let me know your thoughts here.

EDIT: I added them anyways, I still think docker tests are the way to go though.

@pbelskiy
Copy link
Owner

pbelskiy commented Sep 25, 2023

@GeneMyslinsky yes, you must add tests with mock, to check that URLs are formed correctly.
You can look on examples in tests/* directory.

Using real Jenkins instance and integration tests here is over-engineering and not correct I suppose.

I did it in far past here https://github.com/pbelskiy/aiojenkins but It's not good practice due to a lot of cons than pros.

tests/test_builds.py Outdated Show resolved Hide resolved
tests/test_builds.py Outdated Show resolved Hide resolved
ujenkins/endpoints/builds.py Show resolved Hide resolved
ujenkins/endpoints/builds.py Outdated Show resolved Hide resolved
@GeneMyslinsky
Copy link
Contributor Author

@GeneMyslinsky yes, you must add tests with mock, to check that URLs are formed correctly. You can look on examples in tests/* directory.

Using real Jenkins instance and integration tests here is over-engineering and not correct I suppose.

I did it in far past here https://github.com/pbelskiy/aiojenkins but It's not good practice due to a lot of cons than pros.

I like that test suite you have in aiojenkins, because it is essentially a library of examples.
Out of curiosity why did you decide against going that route? What were the cons?

response = client.builds.get('job', fields=fields, start=1, end=3)
assert len(responses.calls) == 1
requested_url = responses.calls[0].request.url
expected_url = 'http://server//job/job/api/json?tree=allBuilds%5Bnumber,url%5D%7B1,3%7D'
Copy link
Owner

Choose a reason for hiding this comment

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

it's incorrect, because we are pinned on http://server? Need to check url, please see the examples.

Moreover I suggest you to check all possible parameters

  1. With only start
  2. With only end
  3. With start and end
  4. Without it
  5. Check that fields forms correctly

test: test_get_selective - url verification
fixup docstring format
some naming changes

space between lines in docstring

add parameterized tests

add expected failure to tests
Possible values are mentioned in the available fields.
If empty, default fields will be returned.

start (Optional[int]): The start index of the builds to retrieve.
Copy link
Owner

Choose a reason for hiding this comment

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

Argument description must be on a new line

@responses.activate
def test_get(client):
def test_get(client, args, kwargs, mock_body, expectations):
Copy link
Owner

Choose a reason for hiding this comment

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

Thanks for such serious tests, but I think it over complicated.

It's enough just to check few simple tests cases or correctly formed relative URL.

Pinning on http://server... in test is incorrect due to it's additional dependency, for example if I will check if conftest.py http://server to something else, your tests will be failed, so it's more correctly just to check quiery parameters instead of full absolute URL.

@pbelskiy
Copy link
Owner

@GeneMyslinsky Thanks for PR, lets do little changes and merge it finally.

About using Docker, I don't like it, because it's slow for local and CI development and testing + additional dependencies and so on. I suppose it's enough to check it locally and then add mock.

@pbelskiy pbelskiy merged commit a361905 into pbelskiy:master Sep 28, 2023
7 checks passed
@omoria1980 omoria1980 mentioned this pull request May 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants