Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upBug 316 - Load steps YAML from Servo repo #368
Conversation
|
Reviewed 2 of 2 files at r1. buildbot/master/files/config/master.cfg, line 141 [r1] (raw file):
This comment is unclear to me -- I expect that the yaml builder would only parse the YAML file from the Servo repo then hand that config back to the master, yet the comment makes it sound like the yaml builder will be what then runs the loaded steps. Comments from Reviewable |
| yaml_path = "" | ||
|
|
||
| def __init__(self, builder_name, environment, yaml_path): | ||
| print(yaml_path) |
This comment has been minimized.
This comment has been minimized.
| self.yaml_path = yaml_path | ||
|
|
||
| def run(self): | ||
| print(self.yaml_path) |
This comment has been minimized.
This comment has been minimized.
| decodeRC={0: SUCCESS, 1: SUCCESS})] | ||
|
|
||
| # util.BuildFactory is an old-style class so we cannot use super() | ||
| # but must hardcode the superclass here |
This comment has been minimized.
This comment has been minimized.
|
|
||
| # util.BuildFactory is an old-style class so we cannot use super() | ||
| # but must hardcode the superclass here | ||
| self.build.steps = pkill_step + dynamic_steps |
This comment has been minimized.
This comment has been minimized.
aneeshusa
May 13, 2016
Member
Let's use += instead of = for now, so that we have a record of the StepsYAMLParsingStep in the buildbot logs.
| dynamic_steps = [self.make_step(command) for command in commands] | ||
| except Exception as e: # Bad step configuration, fail build | ||
| print(str(e)) | ||
| dynamic_steps = [BadConfigurationStep(e)] |
This comment has been minimized.
This comment has been minimized.
aneeshusa
May 13, 2016
Member
Instead of creating a BadConfigurationStep to raise an exception, we should just raise the exception here since we're already in a step. (It was a separate step before because the parsing was done at Buildbot start-up time, and raising an exception them would kill the Buildbot master.)
| """ | ||
| Step which resolves the in-tree YAML and dynamically add test steps | ||
| """ | ||
| yaml_path = "" |
This comment has been minimized.
This comment has been minimized.
aneeshusa
May 13, 2016
Member
A default of "" seems dangerous. Let's just remove this line entirely.
| Step which resolves the in-tree YAML and dynamically add test steps | ||
| """ | ||
| yaml_path = "" | ||
|
|
This comment has been minimized.
This comment has been minimized.
aneeshusa
May 13, 2016
Member
We should set haltOnFailure = True and flunkOnFailure = True here, just as we do for BadConfigurationStep.
| """ | ||
|
|
||
| def __init__(self, builder_name, environment): | ||
| self.environment = environment |
This comment has been minimized.
This comment has been minimized.
|
|
||
| # util.BuildFactory is an old-style class so we cannot use super() | ||
| # but must hardcode the superclass here | ||
| # TODO: pass environments |
This comment has been minimized.
This comment has been minimized.
| """ | ||
| Smart factory which takes a list of shell commands from a yaml file | ||
| and creates the appropriate Buildbot Steps. Uses heuristics to infer | ||
| Step type, if there are any logfiles, etc. |
This comment has been minimized.
This comment has been minimized.
aneeshusa
May 13, 2016
Member
Please update this comment to make it clear that the YAML file is coming from the main servo/servo repo (and capitalize YAML also).
| @@ -103,6 +103,86 @@ def make_step(self, command): | |||
| return step_class(**step_kwargs) | |||
|
|
|||
|
|
|||
| class StepsYAMLParsingStep(buildstep.BuildStep): | |||
| """ | |||
| Step which resolves the in-tree YAML and dynamically add test steps | |||
This comment has been minimized.
This comment has been minimized.
| dynamic_steps = [BadConfigurationStep(e)] | ||
|
|
||
| # TODO: windows compatibility (use a custom script for this?) | ||
| pkill_step = [steps.ShellCommand(command=["pkill", "-x", "servo"], |
This comment has been minimized.
This comment has been minimized.
aneeshusa
May 13, 2016
Member
Let's not put this step in a list here, since pkill_step is singular.
Instead, we can wrap it in a list by adding a line here:
static_steps = [pkill_step]
and later on using static_steps + dynamic_steps.
(We could also directly use [pkill_step] + dynamic_steps, but I think that's a little less clear.)
|
Since we're just testing the YAML loading, let's get rid of You'll also need to make a PR to servo/servo to add a linux-dev-yaml section in the
I believe we need to create and invoke a Buildbot Please also address the test suite failures from Travis. |
|
@aneeshusa So in my |
|
@anneeshusa Also I have a question regarding @edunham 's comment. If I change the Or perhaps I should just return the parsed YAML content back to the master, and let the master start another builder with the parsed steps? But I don't see a clear place in the |
|
As far as I understand, you're correct that you'll need to DynamicServoYAMLBuilder should pick up on the new steps and continue to run them. Buildbot 9 (next major version) explicitly adds support for this behavior: docs here and code here. I think the end result should look pretty close to the |
|
|
|
@aneeshusa Thanks! Let me read that and get back to you. |
|
@aneeshusa I ran the script throught REPL and didn't see any error, but I might need a full setup to varify it works. |
| @@ -103,6 +104,95 @@ def make_step(self, command): | |||
| return step_class(**step_kwargs) | |||
|
|
|||
|
|
|||
| class StepsYAMLParsingStep(buildstep.ShellMixin, buildstep.BuildStep): | |||
| """ | |||
| Step which resolves the in-tree YAML and dynamically add test steps. | |||
This comment has been minimized.
This comment has been minimized.
| yield self.runCommand(cmd) | ||
|
|
||
| if cmd.didFail(): | ||
| raise Exception(str(cmd.result())) |
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jun 8, 2016
Member
I don't think there's a result method on RemoteShellCommand.
It may be better to capture stderr and output that, or maybe return a message with the return code (cmd.rc).
| collectStdout=True) | ||
| yield self.runCommand(cmd) | ||
|
|
||
| if cmd.didFail(): |
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jun 8, 2016
Member
We should check that the result is SUCCESS, not just that it didn't fail, because there are other possible results (e.g. WARNING, RETRY, etc.). We can use this snippet from the Buildbot 9 docs:
result = cmd.results()
if result != util.SUCCESS:
# raise here
# continue extracting stdout and building steps, etc. here
| commands = builder_steps[self.builder_name] | ||
| dynamic_steps = [self.make_step(command) for command in commands] | ||
| except Exception as e: # Bad step configuration, fail build | ||
| # Capture the expception and re-raise with a friendly message |
This comment has been minimized.
This comment has been minimized.
|
|
||
| self.build.steps += static_steps + dynamic_steps | ||
|
|
||
| defer.returnValue(cmd.reslts()) |
This comment has been minimized.
This comment has been minimized.
| def run(self): | ||
| try: | ||
| full_yaml_path = os.path.join(self.build.workdir, self.yaml_path) | ||
| print_yaml_cmd = "cat {}".format(full_yaml_path) |
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jun 8, 2016
Member
I believe the command will be run in the workdir by default, so just passing self.yaml_path as a relative path should work. Also, I don't think the current code wouldn't work for Windows, as the os.path.join would take place on the master (and use /), but the generated command would actually execute on the worker.
| if cmd.didFail(): | ||
| raise Exception(str(cmd.result())) | ||
| else: | ||
| builder_steps = yaml.load(cmd.stdout) |
This comment has been minimized.
This comment has been minimized.
| self.yaml_path = yaml_path | ||
|
|
||
| @defer.inlineCallbacks | ||
| def run(self): |
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jun 8, 2016
Member
Just for now, can you also wrap the entire run function in a try/except block? I want to make sure that the Buildbot master process doesn't come down even if this code doesn't work properly. Once it's working we can get rid of it.
This comment has been minimized.
This comment has been minimized.
| flunkOnFailure = True | ||
|
|
||
| def __init__(self, builder_name, environment, yaml_path): | ||
| self.builder_name = builder_name |
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jun 8, 2016
Member
I believe you also need to setup the shell mixin and call BuildStep.__init__ as done in the example in the Buildbot Nine docs.
|
Please also rebase when you address the review comments. Looks pretty close, so I'm hoping this works on the first try! |
5f2dad9
to
3ae16e1
| @@ -158,6 +177,9 @@ c['builders'] = [ | |||
| factory=factories.doc, | |||
| category="auto", | |||
| ), | |||
| # Testing the In Tree YAML build | |||
| DynamicServoYAMLBuilder("linux-dev-yaml", LINUX_SLAVES, | |||
| envs.build_linux_headless) | |||
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jun 17, 2016
Member
envs.build_linux_headless has been removed; use envs.build_linux instead. (I think it might fit on the previous line, not sure.)
| result = cmd.results() | ||
| if result != util.SUCCESS: | ||
| raise Exception( | ||
| "Command failed with return code: {}" + str(cmd.rc) |
This comment has been minimized.
This comment has been minimized.
| # Capture the exception and re-raise with a friendly message | ||
| raise Exception("Bad configuration, " + | ||
| "unable to convert to steps" + | ||
| str(e)) |
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jun 17, 2016
Member
Let's change this block so that the error message is uninterrupted (e.g. greppable) and a little friendlier:
raise Exception("Bad steps configuration for {}: {}".format(
self.builder_name,
str(e)
))
|
|
||
| defer.returnValue(result) | ||
| except Exception as e: | ||
| print(str(e)) |
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jun 17, 2016
Member
Please re-raise the exception so that the build fails and we're notified. (Otherwise it may silently succeed if the new steps haven't been added yet!)
This comment has been minimized.
This comment has been minimized.
aneeshusa
Jun 17, 2016
Member
Actually, the entire outermost try/except block isn't helpful and we don't need it, because Buildbot handles exceptions safely (e.g. http://build.servo.org/builders/mac-rel-css/builds/1606). Please remove it, sorry for the go-around.
|
This looks good to me, let's see what Buildbot thinks of it. @bors-servo r+ |
|
|
Bug 316 - Load steps YAML from Servo repo This should fix #316 I only tested it with `buildbot checkconfig master` (in the `servo-master1` VM). I did try to execute the step in the python interactive console, but some part requires extensive mocking, so I gave up and submit a PR first. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/saltfs/368) <!-- Reviewable:end -->
|
|
shinglyu commentedMay 10, 2016
•
edited by larsbergstrom
This should fix #316
I only tested it with
buildbot checkconfig master(in theservo-master1VM). I did try to execute the step in the python interactive console, but some part requires extensive mocking, so I gave up and submit a PR first.This change is