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 test to verify if all homu builders are listed in the buildbot config #571

Merged
merged 1 commit into from Jan 11, 2017

Conversation

@charlesvdv
Copy link
Contributor

charlesvdv commented Jan 2, 2017

That should resolve the #443.


This change is Reviewable

@highfive
Copy link

highfive commented Jan 2, 2017

Thanks for the pull request, and welcome! The Servo team is excited to review your changes, and you should hear from @aneeshusa (or someone else) soon.

@charlesvdv charlesvdv force-pushed the charlesvdv:validbuilders branch 2 times, most recently from 9eb326e to 4c42c60 Jan 2, 2017
@charlesvdv
Copy link
Contributor Author

charlesvdv commented Jan 2, 2017

The tests are failing because buildbot is installed in the python3 library folder and not the python2 but buildbot is a python2 package which is required to import master.cfg. I don't really know what solutions could be the best:

  • symlink
  • install buildbot with pip2 (is Salt even support this ? With a quick look at the doc I don't see any ways to change the pip version)
  • add a sys.path.append before the dynamic import

Or maybe another idea I didn't think of ?

Copy link
Member

aneeshusa left a comment

The approach overall looks good; thanks for tackling a less-easy issue!

import sys

if __name__ == '__main__':
sys.path.append('/home/servo/buildbot/master/')

This comment has been minimized.

@aneeshusa

aneeshusa Jan 2, 2017

Member

Pull this path out into a constant.


config = imp.load_source(
'config',
'/home/servo/buildbot/master/master.cfg'

This comment has been minimized.

@aneeshusa

aneeshusa Jan 2, 2017

Member

Use os.path.join to join the constant and master.cfg.

for sched in config.c['schedulers']:
if sched.name == 'servo-auto':
out = {'builders': sched.builderNames}
print(json.dumps(out))

This comment has been minimized.

@aneeshusa

aneeshusa Jan 2, 2017

Member

Add a return 0 after printing to indicate success and exit early. After the loop (meaning servo-auto was not found, print an error message to sys.stderr (e.g. error: 'servo-auto' scheduler not found) and add a return 1`.

from tests.util import Failure, Success


def is_builders_valid(buildbot, homu):

This comment has been minimized.

@aneeshusa

aneeshusa Jan 2, 2017

Member

grammar: is_builders_valid -> are_builders_valid

homu_buildbot = homu_cfg['repo']['servo']['buildbot']

ret = subprocess.run(
['python2', 'tests/sls/homu/get_buildbot_cfg.py'],

This comment has been minimized.

@aneeshusa

aneeshusa Jan 2, 2017

Member

You'll need to use /usr/bin/python2. This is because Travis's only has one "mega" Trusty image, on which it installs all its Pythons, Rubies, etc., and the $PATH always contains all of those Pythons before the main /usr/bin, etc. entries. Hence, just python2 invokes a Python from /opt, not the main Python that we want.

(This will fix the tests currently failing.)

This comment has been minimized.

@aneeshusa

aneeshusa Jan 2, 2017

Member

Also, right now the rest of the test suite is agnostic to CWD, so I'd prefer to refer to the get_buildbot_cfg.py file differently, likely using __file__.

)
if not is_builders_valid(buildbot_builders, homu_buildbot['try_builders']):
return Failure(
'Homu config is not in sync with the buildbot config', ''

This comment has been minimized.

@aneeshusa

aneeshusa Jan 2, 2017

Member

Have this and the previous message be different (ie. reference builders vs try_builders) to the error message is immediately helpful.

This comment has been minimized.

@aneeshusa

aneeshusa Jan 2, 2017

Member

Additionally, we should make use of the second argument to Failure. To check validity, cast the homu builders and buildbot builders to lists, then subtract the sets to perform a diff. If the len() of the diff is non-zero, then pretty-print the mismatched (i.e. remaining in the diff) values to use for the second argument to Failure().

'Homu config is not in sync with the buildbot config', ''
)

return Success('Buildbot and homu configs are synced.')

This comment has been minimized.

@aneeshusa

aneeshusa Jan 2, 2017

Member

nit: No period at the end

@charlesvdv charlesvdv force-pushed the charlesvdv:validbuilders branch from de9f6a4 to 2d1da66 Jan 3, 2017
Copy link
Member

aneeshusa left a comment

Good progress! I've left some comments to make this code more Pythonic.
Also, please rebase on top of the latest master to pull in #573.

BUILDBOT_MASTER_PATH = '/home/servo/buildbot/master/'

if __name__ == '__main__':
sys.path.append(BUILDBOT_MASTER_PATH)

This comment has been minimized.

@aneeshusa

aneeshusa Jan 6, 2017

Member

Let's move this code into a main() function and use return instead of exit in main(); here it can be called as sys.exit(main()).

print(json.dumps(out))
exit(0)

sys.stderr.write('error: "servo-auto" scheduler not found\n')

This comment has been minimized.

@aneeshusa

aneeshusa Jan 6, 2017

Member

Prefer print(..., file=sys.stderr).



def get_script_path():
dirname = os.path.dirname(__file__)

This comment has been minimized.

@aneeshusa

aneeshusa Jan 6, 2017

Member

This can be inlined into the next line (should fit within 80 char limit).

This comment has been minimized.

@aneeshusa

aneeshusa Jan 6, 2017

Member

Also, the whole method can then be inlined into run().

This comment has been minimized.

@aneeshusa

aneeshusa Jan 6, 2017

Member

It would also be nice to add a comment about why we need to invoke a Python2 subprocess to run the separate script.


def are_builders_valid(buildbot, homu_cfg, buildertype):
for builder in homu_cfg[buildertype]:
if builder not in buildbot:

This comment has been minimized.

@aneeshusa

aneeshusa Jan 6, 2017

Member

The set differencing subsumes the need to loop over each builder and check if it is present or not, so these first two lines aren't needed.

from tests.util import Failure, Success


def are_builders_valid(buildbot, homu_cfg, buildertype):

This comment has been minimized.

@aneeshusa

aneeshusa Jan 6, 2017

Member

Inline are_builders_valid into run(), which allows removing a bunch of duplicated error checking.

def are_builders_valid(buildbot, homu_cfg, buildertype):
for builder in homu_cfg[buildertype]:
if builder not in buildbot:
diff = list(set(homu_cfg[buildertype]) - set(buildbot))

This comment has been minimized.

@aneeshusa

aneeshusa Jan 6, 2017

Member

No need to cast to a list.

diff = list(set(homu_cfg[buildertype]) - set(buildbot))
diff_print = ''
if len(diff) != 0:
diff_print = 'Difference: {}'.format(diff)

This comment has been minimized.

@aneeshusa

aneeshusa Jan 6, 2017

Member

This can be inlined into the Failure constructor.

diff_print = 'Difference: {}'.format(diff)

fail = Failure(
'Homu "{}" config isn\'t sync with buildbot config'

This comment has been minimized.

@aneeshusa

aneeshusa Jan 6, 2017

Member

nit: sync -> synced
Also, using double quotes for this string will make it easier to read (no need to escape the apostrophe).


def run():
homu_cfg = toml.load('/home/servo/homu/cfg.toml')
homu_buildbot = homu_cfg['repo']['servo']['buildbot']

This comment has been minimized.

@aneeshusa

aneeshusa Jan 6, 2017

Member

I think homu_builders is more clear.


buildbot_builders = json.loads(ret.stdout.decode('utf-8'))['builders']

resp = are_builders_valid(buildbot_builders, homu_buildbot, 'builders')

This comment has been minimized.

@aneeshusa

aneeshusa Jan 6, 2017

Member

You can use a loop to cut down on some duplication:

for builder_type in ['builders', 'try_builders']:
    diff = ....
    if diff:
        return Failure(...)

return Success(..)
@charlesvdv charlesvdv force-pushed the charlesvdv:validbuilders branch from 2d1da66 to 16b13b5 Jan 6, 2017
@charlesvdv charlesvdv force-pushed the charlesvdv:validbuilders branch from 16b13b5 to 00ecc87 Jan 6, 2017
@charlesvdv
Copy link
Contributor Author

charlesvdv commented Jan 6, 2017

@aneeshusa This should be OK now!

Sorry for the long review process 😞

Copy link
Member

aneeshusa left a comment

I was testing this out and we can make the error reporting more helpful. Currently, we early return if any builder set has invalid builders, but we should buffer all differences and return them together at the end.


buildbot_builders = json.loads(ret.stdout.decode('utf-8'))['builders']

for buildertype in ['builders', 'try_builders']:

This comment has been minimized.

@aneeshusa

aneeshusa Jan 7, 2017

Member

nit: buildertype -> builder_set

diff = set(homu_builders[buildertype]) - set(buildbot_builders)
if diff:
return Failure(
"Homu {} config isn't synced with buildbot config"

This comment has been minimized.

@aneeshusa

aneeshusa Jan 7, 2017

Member

nits:

  • add a colon at the end
  • capitalize Buildbot
return Failure(
"Homu {} config isn't synced with buildbot config"
.format(buildertype),
'Difference: {}'.format(diff)

This comment has been minimized.

@aneeshusa

aneeshusa Jan 7, 2017

Member

Before the for loop, initialize a string var (e.g. failure_msg) to an empty string. In the loop, if the if diff: condition is true, append information about the diff to failure_msg.

After the loop, if failure_msg then return a Failure passing failure_msg for the second argument. This way if there invalid builders for builders and try_builders they're both reported.

Prose changes:

  • Keep the same title (first arg) for the Failure, but don't mention the builder set
  • Use a more descriptive prefix than Difference, maybe Invalid builders for {builder_set}: (this gets added to failure_msg iteratively)
)
if ret.returncode != 0:
return Failure(
'Unable to retrieve buildbot builders name:', ret.stderr

This comment has been minimized.

@aneeshusa

aneeshusa Jan 7, 2017

Member

nit: Use 'Unable to retrieve Buildbot builders:'

homu_builders = homu_cfg['repo']['servo']['buildbot']

# We need to invoke a new process to read the buildbot master config
# because buildbot is written in python2.

This comment has been minimized.

@aneeshusa

aneeshusa Jan 7, 2017

Member

nit: capitalize both instances of Buildbot

@charlesvdv charlesvdv force-pushed the charlesvdv:validbuilders branch from 00ecc87 to 5ab75c2 Jan 7, 2017
Copy link
Member

aneeshusa left a comment

Sorry about the long review, you're almost there!

if diff:
if failure_msg:
failure_msg += '\n'
failure_msg += 'Invalid builders for "{}": {}'.format(builder_set, diff)

This comment has been minimized.

@aneeshusa

aneeshusa Jan 10, 2017

Member

Linter says this line is too long.

diff = set(homu_builders[builder_set]) - set(buildbot_builders)
if diff:
if failure_msg:
failure_msg += '\n'

This comment has been minimized.

@aneeshusa

aneeshusa Jan 10, 2017

Member

You can actually include the \n unconditionally as part of the format string - the outputter is smart and will strip the last trailing newline.

@charlesvdv charlesvdv force-pushed the charlesvdv:validbuilders branch from 5ab75c2 to 16d83db Jan 10, 2017
@aneeshusa
Copy link
Member

aneeshusa commented Jan 11, 2017

Thanks for tackling this! @bors-servo r+

@bors-servo
Copy link
Contributor

bors-servo commented Jan 11, 2017

📌 Commit 16d83db has been approved by aneeshusa

@bors-servo
Copy link
Contributor

bors-servo commented Jan 11, 2017

Test exempted - status

@bors-servo bors-servo merged commit 16d83db into servo:master Jan 11, 2017
2 checks passed
2 checks passed
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test exempted
Details
bors-servo added a commit that referenced this pull request Jan 11, 2017
Add test to verify if all homu builders are listed in the buildbot config

That should resolve the #443.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/saltfs/571)
<!-- Reviewable:end -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

4 participants
You can’t perform that action at this time.