IRC logs for #buildstream for Tuesday, 2017-12-19

*** mcatanzaro has joined #buildstream02:26
*** valentind has joined #buildstream08:36
gitlab-br-botbuildstream: merge request (master->master: WIP: Documentation improvements) #183 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/18309:04
*** tiago has joined #buildstream09:12
*** noisecell has joined #buildstream09:29
*** valentind has quit IRC09:31
*** tpollard has joined #buildstream10:13
*** ssam2 has joined #buildstream10:17
gitlab-br-botbuildstream: issue #173 ("Element state / cache key handling") changed state ("opened") https://gitlab.com/BuildStream/buildstream/issues/17310:30
tlaterIs there any reason to use the click runner over subrpocess.check?10:50
* tlater is struggling enough trying to whip this in to place that he's considering just using subprocess... 10:51
ssam2it avoids a fork() and exec()10:51
ssam2i don't know if that matters at all, though10:51
tlaterIt seems to do magic to file descriptors that's incompatible with other things, though...10:52
ssam2yes10:53
ssam2the docs themselves say this: 'This only works in single-threaded systems without any concurrency as it changes the global interpreter state.'10:53
ssam2i don't fully understand what that is implying though10:53
ssam2http://click.pocoo.org/5/api/#testing10:53
ssam2perhaps it's just referring to the way it modifies sys.stdin/out/err10:54
tlaterI guess it does catch exceptions neatly10:55
persiaI think it means that if you try to use that as a thread in a larger application, the global state change for the individual thread will affect the rest of the application (so don't: instead restrict use to single-threaded calls).11:14
*** jude has joined #buildstream11:32
tlaterSo it looks like passing the sys.* objects created by pytest to subprocess.Popen causes the subprocess to hang11:40
* tlater figures this is deadlock because the parent process and the child process attempt to write to the same file11:42
tlaterThe only way I can see this working is if the sandbox subprocesses write to a pipe and then write all their stdout/stderr to sys.stdout/sys.stderr after they finish11:42
ssam2watching output of subprocesses is always painful in python11:45
ssam2do you know it's due to pytest creating the sys.stdin/out/err objects?11:46
ssam2it's easy to hang even with the default stdin/stdout/stderr11:46
ssam2if you don't read from the pipe in the parent process, the child process blocks as soon as it fills up the buffer11:46
tlaterI've never seen a hang for this reason outside of these test cases, so I'm fairly sure11:47
ssam2"fairly sure" is rarely good enough when dealing with software :=)11:47
tlaterFair enough, I don't really see a way to be more certain though11:47
ssam2you should be able to run the test as a standalone program easily enough ?11:48
ssam2just add a call at the bottom of the script to call the test function11:48
tlaterYep, that I have done11:48
ssam2ah, then pytest shouldn't be messing with sys.stdin/out anyway I don't think11:48
tlaterI've also replaced sys.stdout with None in the actual code, which seems to prompt python to create a new stdout for that process11:48
ssam2if it does that when you just import the module, it's a bad bad panda11:48
tlaterNah, it doesn't, luckily11:48
tlaterBut the reason behind the earlier error is that python creates new std* file descriptors for subprocesses11:49
tlaterWhich means that the original one we are capturing from isn't written to11:49
tlaterWhich in turn means we can't get subprocess output11:49
ssam2right11:49
tlaterNow, trying to swap that out for our current file descriptor causes deadlock11:50
ssam2using stdout=subprocess.PIPE is probably the best option then, indeed11:50
ssam2i always find myself using that to be honest11:50
tlaterIn that case, we would be changing buildstream functionality though11:50
ssam2when faced with problems like this11:50
ssam2hm ? i thought this was only the test runner11:50
tlaterNo, this is testing the `bst shell` code11:50
tlaterAnd because that launches a subprocess...11:50
ssam2right11:51
ssam2but why not launch `bst` itself as a subprocess ?11:51
tlaterI'm still trying to use the click test launch thing11:51
tlaterThough I'm really considering throwing that out11:51
ssam2personally, if you can replace it i would say that's no bad thing11:51
ssam2this is another situation where Python's stdlib is pretty lacking11:52
ssam2there's no way to start a process and then read from stdout/stderr as it runs11:52
ssam2i must have written code to do that a dozen times already, always slightly different11:52
tlaterYeah, it would be nice to have11:52
ssam2but anyway, the click thing is not that smart, we already hit limits of it (no separate stderr/stdout feeds) and it's clearly unmaintained11:53
* tlater removes it and the hack tristan installed to work around stderr/stdout splitting11:53
ssam2so... all we really gain is this smart way of avoiding a fork() and exec() every time we start an instance of `bst` from the tests11:53
tlaterIt also catches exceptions11:54
ssam2ah true11:54
ssam2that's pretty useful for testscases indeed11:54
tlaterI don't think it's possible to do that with a fork() and exec() unfortunately11:54
ssam2yeah11:55
ssam2still, from the point of view of the integration tests this isn't a regression as we already couldn't do that11:56
ssam2if the existing test suite uses click.CliRunner and the integration tests use something else, we're still in a better position than before11:56
tlaterI'd rather use the same functions for both, tbh, but I guess there's no helping it11:57
persiaThe CliRunner docs fairly strongly assert they are to be used for unit tests, and not other sorts, encouraging the split11:58
*** jude has quit IRC12:03
tlater\o/ Finally have a successful test case :)12:23
gitlab-br-botbuildstream: merge request (sam/savefile-utility->master: utils.py: Add SaveFile utility class) #179 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/17912:24
tristantlater, ssam2, we probably want to make public API out of `tests/testing` module14:50
tristanand share that between the "integration" tests and other regression tests14:51
tristanbut not before 1.014:51
tristanotherwise, how will third party plugin repos use the test fixtures; write it all by hand ? meh...14:52
ssam2makes sense15:16
tlaterpytest.parametrize is so handy for integration tests :)15:41
* tristan not sure what the above thing is really about, we could run the exec but then we'd have to provide the entry point15:42
tristan(so that tests are not dependent on install)15:43
ssam2oh that's true15:43
tristanalso, we want to refactor the exceptions into error domains/codes15:43
tristanwhere we have like LoadErrorReason already for load domain15:43
tlaterWith the stderr/stdout redirection we can't get the actual exception object in integration tests15:44
tristanideally we get it all machine readable, we *could* have a way for the app to communicate it back to the caller, if that makes sense15:44
tristanI dont expect to be able to pass an exception object between processes15:44
tlaterSo instead you suggest a neater way of outputting exceptions?15:45
*** mcatanzaro has joined #buildstream15:45
tristantlater, I think you want to be using the same fixtures as in tests/15:45
tlaterI am for the *most* part, but I can't use the click test runner15:46
tristantlater, I would, but not if it's unnecessary.15:46
tristantlater, we dont use the click test runner15:46
tristanand why not ?15:46
tlaterBecause `bst shell` runs a subprocess, and I've been unable to capture stdout of that subprocess through the click test runner.15:47
tristan(we used to use the click test runner, but now we just invoke the cli() directly with a pytest hack)15:47
tlaterI'm referring to this: cli.main(args=args or (), prog_name=cli.name, **extra)15:47
tlaterSupposedly that's the click test runner?15:47
tlaterOr part of it, anyway15:48
tristannot anymore15:48
tristanwe used to use CliRunner15:48
tlaterHm, well, either way, it runs buildstream in the same process, which makes it very difficult to get stdout from its subprocesses15:48
tristantlater, it's actually cli() defined in _frontend/main.py15:49
tlaterAh, fair enough15:49
tristanso you are basically saying that child processes dont inherit the same stdout/stderr ?15:50
tlaterYes, and if you force them to, you end up with deadlock15:50
tristanwhat is "force them" ?15:51
tlaterSetting stdout of the suprocess.Popen call to sys.stdout15:51
tlaterWhich, by default, is set to "None"15:51
tlaterAnd *should* make them get sys.stdout, but presumably that's a different file descriptor, which means that our wrapping code doesn't capture it.15:52
tristantlater, you *might* try FDCapture instead of SysCapture in tests/testutils/runcli.py15:53
tristanthat should capture the stdout/stderr at the os level instead of the python sys level15:54
tlaterHm, that's worth a try15:54
tristanif it works as advertised, not sure that's what it's for15:54
* tristan notes that pytest is itself running the same captures; so we are already a capture within a capture15:56
tristanstuff we print in runcli.py only gets passed back to pytest15:56
tlatertristan: The FDCapture works \o/16:01
tristantlater, nice :D16:02
tlaterWell, at least with the new tests16:02
tlaterHere's hoping it doesn't break the already existing tests16:03
* tristan would not be against changing the whole thing to launch an exec, but that's a bit involved and deserves to be it's own topic16:03
tlaterWell, it's not too big of an issue anymore now, and it means that we gain some small benefits... All it really costs us is some slightly more complex cli wrapper code.16:05
* tristan thinks it's nicely isolated and replaceable anyway; we could throw it away and change it at any time without having to rewrite tests16:06
* tlater in fact did just that for a little while to test his integration tests; it's very easy to overwrite the invoke() method16:07
tristanso I guess feel free to `git mv tests/testing buildstream/_testing` for your purposes16:08
tristanthen we can later polish it up and make it `buildstream/testing` and public16:08
tristanoh it's currently testutils16:08
*** noisecell has quit IRC16:17
* paulsherwood wonders whether he can yet expect to 'get started' smoothly with buildstream16:37
tlaterThere are a few documentation pages coming up with what you need to 'get started', they should land around 1.0 :)16:42
*** tristan has quit IRC16:51
paulsherwoodtlater: pls can it be sooner than that? i have a window to look at this over the xmas break... if it's not ready, i'll miss it17:09
tlaterHm, with a bit of luck we'll be pushing them tomorrow17:10
* paulsherwood crosses fingers17:10
tlaterWhich reminds me, I should probably review this today so that tings go smoothly17:10
gitlab-br-botbuildstream: merge request (sam/meson->master: WIP: use Meson instead of setuptools to install and distribute BuildStream) #196 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/19617:13
ssam2profiling `bst shell`, it seems we spend loads of time in os.realpath17:27
ssam2from _ensure_real_directory17:27
ssam2this profiling method doesn't measure the FUSE code though, which is a bit useless17:31
ssam2commenting out the realpath() calls in _ensure_real_directory() makes the link_files() call go from 26 seconds to 6 seconds, so we will have to figure something out there17:32
ssam2i don't think it can just be removed though17:33
bochechassam2: 20 seconds to resolve symlinks? o_O17:33
ssam2i think the issue is Python implements realpath() itself, in Python17:34
ssam2we have 1000s of files, and its just doing loads of slow string processing17:34
ssam2if we could use realpath() from glibc it would probably be much faster17:36
ssam2anyway, i guess i need to open issues for these things and do more profiling, rather than spewing thoughts into IRC :-)17:37
bochechaPython's realpath is surprising :-/17:37
bochechapath, ok = _joinrealpath(filename[:0], filename, {})17:37
ssam2yeah17:38
bochechaI'm pretty sure that `filename[:0]` is just the empty string :)17:38
ssam2yeah I puzzled over that one17:38
ssam2but I think it's because joinrealpath checks if that is bytes or string17:38
bochechait could do that on filename, though17:39
bochechaseems more like _joinrealpath is called recursively, so the first call has one parameter empty17:40
ssam2true17:40
ssam2ah yeah17:40
bochechabut then it does `os.readlink` on each component of the path? that's... it's too late to be reading this kind of code :P17:41
gitlab-br-botbuildstream: merge request (sam/meson->master: WIP: use Meson instead of setuptools to install and distribute BuildStream) #196 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/19618:01
gitlab-br-botbuildstream: issue #174 ("Python os.realpath() function is too slow") changed state ("opened") https://gitlab.com/BuildStream/buildstream/issues/17418:10
*** noisecell has joined #buildstream18:12
*** noisecell has quit IRC18:13
*** tristan has joined #buildstream18:19
*** valentind has joined #buildstream18:38
*** ssam2 has quit IRC18:52
*** tiago has quit IRC20:00
*** tristan has quit IRC21:00
*** mcatanzaro has quit IRC21:11
*** valentind has quit IRC22:41
*** semanticdesign_ has quit IRC23:47

Generated by irclog2html.py 2.15.3 by Marius Gedminas - find it at mg.pov.lt!