 Felly, yna gydag yno gael y niforol yn gweithio i mi, yn gweithio i mi. Felly, rwy'n Philip Hans, ehm, sydd yn cyfaniadau yn y Debyg a'r ysgwrdd a'r ysgwrdd, felly y gwybod a'r ysgwrdd yn gweithio i mi yn gweithio gweithio gweithio'n gweithio'n gweithio'n gweithio'n gweithio'n gweithio'n gweithio, Alexander y Tysgr, rwy'n enw i'n cymaint, rwy'n rwy'n dweud. Felly hi, ychydig! Mae'n gweithio'r cyfeiri, boeddartwch byddwn i gweithio am y plaig. Dwi'n eitio'r dda i'r rhaid i'r ddweud o'r ddweud o'r ddweud, mae gennym yw'r llwio'r cerddau yn gwirio'r llwio'r llwio'r cyfeirio'r ddweud. Mae gennym yn defnyddio'r ddweud o'r ddweud o'r ddweud o'r ddweud o'r dysgu. ychydig yn ysgol yw'r tympai, a gweithio'r cyflwyno gyda'r ymwneud yn dweud yn y cyflwyno, a rydyn ni'n gweithio'r tympai ar y cyflwyno ar gyfer y dweud. A rydyn ni'n gweithio'r tympai ar gŵs, a'r tympai o'r cyflwyno a'r ddweud yn y cyflwyno. A'r tympai ar gyfer y ddweud. Felly, gydag i'w ddweud yn ymdwy'n meddwl i fynd i ddechrau ar y cyflwyno, a'r cyflwyno ar gyfer y ddweud, eich tunio'r tyd i gael i gennym ac mae'n ddweud honno i'n amheliad mewn cyntaf sydd yn dweud yn lluniau ac mae'n rhaid i beth ychydig o'r mawr felly cael ei ddymiadol arall a mae'n amluaen gweithio ni'n amluaen ac mae'n o'r sgwrdd ei ddweud a mor iawn heb yw'r prospec felly mae'r ystafell flwythus ond mae bod yn diweddal sydd yma'n cael eu bod yna'i enliad A dyma'r ddod o'i'r ddechrau felly, bydd y desses yn gweld yma ac mae eich erbyn yn rhoi gweld. Felly mae yna yma. Yna yma y mynd yma, y y tu yn rhoi gweld. Yr prymau yma mae'n gwneud i ddechrau'n ysgrifennu'r ysgrifennu a dyna ein bod fydd y gallwn ni'n amser hynny. Pethau'n rhaid, mae'n detall yn drafodraen na'r gofynn. You read that, OK? So this is a test-rigger of Jenkins because we inadvertently upgraded Jenkins on the main Jenkins server last night and the triggers broke in a different way. So, at the moment the push isn't working but everything else is working here, I think. Sometimes it carries on going for ages and then some minor plug-in upgrade means that the bits you can figure it with ac mae oeddaf yn bob sgwpeth o'i ddweudio'n hoffa, mae oeddaf yn dweudio'n hoffa ymlaen. Gweithio'n ddwy'n ddweudio. Ac mae'n fydd yn fwyaf. Dwi'n meddwl, dwi'n meddwl. Dwi'n meddwl. Aroedd o'r bydd yn fwyaf. Mae'n meddwl, mae'n meddwl. Mae'n meddwl. Dwi arno. Mae oeddaf yn gweithio'n meddwl. Mae'n meddwl. Felly, ystod y cynghoraeth fel ei wneud hwn yn eich gweld, mae'n golygu ynddig yn ei gtwyr yn y fawr. Dyma yna o'r unseidiau u debyg, ond felly eich gwaith yn gweithdfodd ond iddo wedi mysiu'r ysgrifwyr. Felly, ydiad y nextio'r ysgrifwyr, eich gweithdd, yna hwn yn ei ddiwedd eich cynghori.. ..id oed yn cael'r ysgrifwyr a'i gweithdynt yn gweithfodol i'r ysgrifwyr yn cael'u gweithfodd. Felly mae'r ffordd ydyn nhw, ac mae'n meddwl iawn i gaf o'r cwmnu i'r bwfferddau, bobi'n ddefnyddio i ddaeth hynny. Rydym wedi ei falch efo. Felly mae'r awddiadau yn unig. Mae'r ddaeth yn brifio. Merthifael. Felly mae'r ddaeth wedi cael ei bywyd. ..aeth hyn y maen nhw'n gwrs... But. Ychydig. Ac ydy yw bod dyna cyflwydd. Mae wedi ddweud eich cyfrwp ar gyfer yr awr... ..y'r tyn ni'n ei ffaith o'r whit yn 2010... ..dydyn ni'n gymholll, ddim yno ar ei amddir yn cyfleoedd... ..yna'n gallu ychydig. Felly mae wedi weithio'r hwynt. So, dyna'r gwlad i'r newid, mae'n gweithio i'r awdd, ac mae'n gweithio i'r awd, ac mae'n gweithio i'r newid. Mae'r ddiwedd i'r ceisio yn ymddangos. Felly mae'n cael ei ddweud... Ac ydych chi'n meddwl i'r gwahodnaf yn ymddangos yma, i wneud yma y dyfodol yn y syniadol diolethaf diolethaf. Mae'r pwysig yn ymddangos i gyda phosib. sy'n tychu dyma'r ystyth yn nidio ddechrau'r rhannu yn Passyfau, ac mae'r rhannu yn unrhyw ff folkro gyda ni oherwydd yn arweithio'r rhannu, oherwydd mae'n ddweud y野f yn gwneud i'r rhannu, ond dyma nidio'r rhannu yn gweithio'r rhannu a bywch yn ei casu postiad yn eich ei bwysig ar y gwahanol, ac mae'n ôl eich gwahanol yn ôl, mae'n cyfnod oedd yn cael ei foto o'r cyntaf agor genialiau hwnna. Rydym yn ddiffredigol i'n dod o'r rhannu Something, which means that you can do that in any repository that you run, as long as you get Jenkins to then go and look at that repository in response, which is pretty cool because it means you don't have to have Jenkins checking every ten minutes. You can, as long as it's checking at all, so you can configure it to check once a day or something just to have that box ticked. After that it will react within seconds and quite often I I don't get to the web interface before it's finished for UDEPs, which is really nice. So, what happens then is that Jenkins is provoked into action, and then Jenkins is a, I don't know whether I want to talk about that at the moment, Jenkins is a Java and XML thing, which most people go, ahhh Java, and then, ahhh XML. So, then they, they thought, let's wrap that in Python. So, we've got a thing for taking YAML to XML, so you don't have to worry about XML or Jenkins too much. Then, actually some of the YAML isn't powerful enough. If you want, if you've got a huge matrix of possible tests that you could run, and you only actually want to run a few of them, then it's really difficult to do any YAML. So, we also generate YAML using another layer of Python. That's good. Then, from the testing I'm doing, there's a thing called Cucumber, which, where have we got that? It's one of these. It's a bit of a Cucumber. Right, so Cucumber is this thing that you're meant to point it, point management at, and they can write little scenarios. Because, you know, they're not meant to be, they're not expected to understand you and this stuff. So, you write this, sort of, like English, as a normal user, I should be able to install it in. Fair enough. And I want to, you can, this is a more complicated thing than you get out of a manager, I expect, because I wanted to try several scenarios with several results. And it fills in the blanks. You can see these bits get replaced. So, it saves a lot of typing if you do that. That's written in Ruby, which you can't retell from that. But the reason it, what's actually going on is that they're all Ruby functions using these matching bits. And then it picks out the variables from the English text and that stuff. So, this is waiting for an image that's got name of user in its name. And when it gets it, it types the name and enter. And then it does it again for, it waits for that to go away. And then it looks for other things to come up on the screen, like the user password or the user, the show user password. So, that one's the image where it's got the tick box from the new version that says, I want to show it. And it needs to be able to recognise all these different images. And it's really tedious to do all the screenshots. So, we need to fix the workflow for getting that. But there's meant to be an OCR thing. We'll make it a lot easier because you'll then just be able to say, look for password on the screen. And it can OCR it off the screen. But at the moment, that's really noisy and just logs all over the place. So, that's Cucumber is this thing for controlling stuff, which inside it is actually using a thing called Sicily, which is doing all the image recognition. And that runs a headless X and KVM and like that. So, it all nested together and drives the session. So, you're not preceding it like we normally do our tests with preceding. This is pretending to type on the keyboard. You can also make it say, look for this image on the screen and click to the left of it. And so, you can drive graphical user interfaces with it. Then, underneath the Jenkins stuff, the thing that's actually doing the job are just shell scripts so, my job name is this. Chop bits out of it. Run a shell script and that's how it's all controlled. So, it looks incredibly complicated. There's lots of stuff going on. But actually, it's just a way of running a couple of shell scripts. And if you can join the good jobs together so that when this job runs, if it succeeds, then it runs another job and it takes some of its parameters and passes them on. So, that's how I've got it, so that this sort of worked example that is going on in the Jenkins thing is once you do the push, it builds a U-deb and drops the U-deb into the name of the thing that you pushed. Then, if you've got multiple U-debs like that, it will be dropping all the U-debs into that directory. At the end of it, when it's done that, it builds an installer with those U-debs in the local U-deb directory. So, what you get out of the end of it is the current testing, well, you can decide which version, but the current testing or CID DI with your personal branch U-debs on top, which means that you can test anything you like. You're not doing any harm to anyone unless you're not pushing it into the master branch. And you get a mini ISO out of the end, which you can then boot and do all this stuff to. And if the test has come out the other end, the test that I've been doing most often is doing an install to the end of several desktops, then letting it reboot and seeing whether it manages to get to a login prompt. Obviously, once you've done that, you can do much more because at every stage where a major decision is being made, you can snapshot it. And the snapshots allow you to roll back to just that point. So, if you snapshot it at the point where it's just ready to boot after the first boot, you can then say, actually, I want to see if Firefox is capable of getting on the network. And it's only the installing Firefox and running it a bit that you have to test. And they can have a load of these tests in parallel and it fires through them pretty quickly. So, I've talked about Cucumber a bit. Yeah, the reason I'm using Cucumber is because Tails uses it for their testing. They've got their scenarios tuned to the point that they actually have to have the success branch of what, you know, I found the image pause for 10 seconds because otherwise, if you're making a movie of the test session, it comes up, gets the screenshot that it's looking for and destroys the snapshot before it's even managed to sample it enough to notice it on the video that it's worked. So, they put a 10-second pause in to make sure that you actually get to see that Firefox managed to get on the net and then it disappears and the next thing happens. So, Cucumber, what it's meant for Cucumber is behaviour-driven development. So, you're meant to get your manager to say, we want the product to do this. And when you run that, it complains about the fact that you haven't got any functions to find. And then you're meant to fill in all the functions and then you're meant to write the code and you're meant to end up with a website or something. All the things that are talking about Cucumber are sort of saying, you shouldn't really use it for what we're using it for, but Tails were using it anyway and it did work. So, it took me a while to get to the point where it worked for us. And there's lots of rough edges I could really do with someone that understands Ruby better than I do to sort out all the rough edges. But it does actually work. It's pretty amazing when it does work. So, all the bits could be improved, but as it is, I think it's going to be pretty useful. Cycly is the thing for grabbing screenshots and typing things. You don't really know it. You need to know that. It's got the OCR thing which is coming up. When that happens, it's going to make life a lot easier because you should be able to just say, here's a bit of text that is unique to that screen. And once it comes up, I know that I'm meant to be typing this other thing. At the moment you have to... The workflow I've been doing mostly is that you run the scenario. It gets to the end of it. It fails because you don't know what's meant to be on the screen. It gives you a screenshot. You take the screenshot. You chop out the bit that's going to be unique. You save that in a file. You run the whole thing again. And of course, because this is why it's taken six months, because the early stuff gets fixed quite quickly. Every time you want to test it, it runs out to further away from you and it can be an hour before you find out that you've cropped the image part slightly too small and sickly can't recognise it. Or you've made it not specific enough and it'll recognise it early and then start typing when it shouldn't have done and say that you're three steps beyond what you thought you were. Yeah. But now I'm getting to the point where if you have multiple images that could be on the screen, it tells you which one it's found. There are some race conditions in that because it looks for the first one, looks for the second one, looks for the third one. So if it looks for the first one and then the first one appears, it looks for the second one. If that's quite similar, it might recognise it as that and go off and do something else. So these days what I do is look for the first, look for them all. If it recognises any of them, look for them all again. And that way you can prioritise which one you really want to see and then you don't get so many false positives. There's also a remote shell hack which so you start a TTY on your virtual machine and then you can connect to it. And in Tails they have a particular command line option to boot something like, never do this in production or something. And if that's there it runs this little server which listens for commands and you can tell it to run things as route and it gives you the response, the result codes in JSON. We don't have that thing in DI by default. So at the moment I'm just running a busybox shell and for reasons not apparent you get a double echo and a load of control characters out of every command prompt. The echo for what is actually going on is fine. The output is fine. So with a bit more clever recognition on the Ruby side of things you should be able to pick things out of that. That means, at the moment all I'm doing is, I've got it here. Is there any questions or, you know, is this, am I going too fast, too slow, anything like that? You all okay with this so far? Okay. What? Well, let's throw them in the middle. I don't mind because then I'll have some idea of what's actually interesting people. I don't want to bore you all to death. So, yeah, I really like the way it's actually stacking together even though you've got so many different components. I think it's horrific. Test all the bits actually does work because there's not many other ways of doing that. I know you've got so many different languages involved and you're stitching them together with a cathode but actually getting it to the point where you can actually test that kind of stuff is really important. I'd really like to work out a way of alting a text interaction thing on the back end so that with the same scenario you can say actually I'm going to use SSH over the Met to the target machine because most of the time you don't care whether the colours are right and things like that. If someone changes the background colour on the installer then I imagine all my PNGs will be dead and I'll have to do them all again which will be really tedious. Whereas if you're doing it in text mode and talking to it at virus so you don't have to do any recognition you've just got the text. So, I don't want to replace the cucumber thing because some things you do actually care if there's a bug at the moment where the increased font size option isn't working in DI. So, you actually want to be able to see that the font size is bigger in the graphical installer at that point. Yeah, let's not go to the point of trying to work out whether the installer with speech synthesis actually works and I hope you can test that. Well, yeah, that's got to be worth doing as well because... If you can work out how to do that. Yeah, I don't know how you... because it's going to be pretty similar. The sounds are going to be fairly similar to one another. It's not like speech recognition. You're just recognising that particular noise that it always makes when it's asking you for that prompt. So, I think you should be able to do that and you should be able to say if the noise is vaguely similar with some rubbishy comparison thing, that's probably enough because if it's radically different or it doesn't come out of the speaker at all, then that's bad. So, the testing of the actual text base and SSH and that kind of thing, that's a separate test because you're not testing the way that installer is used on... Well, not really because... It's another parallel test, isn't it? Well, it's sort of... but it's applying the same... you can apply the same test through a different user interface. Okay. A faithfully. So, I've got it at the moment so that in that table of scenarios you can say that I want the VT or the text user interface and I want to install a graphical thing or vice versa, you can do all the combinations with that. Yeah, ideally we should be able to test the whole matrix, isn't it? Yeah, absolutely. Although it's a bit pointless, actually. If you can install it using the graphical installer and all the way to the end and then you can install the same thing in the text installer, it's probably not a point of going through all the desktops in series and then doing both of them. So, it's worth doing one or other than what there are twice. You need to identify which paths and test each path. So, I think as long as you've covered most of the paths then the only reason to do more than that is if you actually find a bug where it only manages to install GNOME if you do it in text mode or something like that. So, I think it would actually be quite nice to use the behaviour-driven development idea by taking things out of the bug-tracking system and saying, this person is saying that they can't do this thing. So, we write down the scenario that they're trying to do that doesn't work as the cucumber thing. And we can start building that and seeing why it doesn't work. By the end of it, you should have a bug fix that sort of ties into that and you just keep the scenario forever when it wants a month. And then that's a bug. I've had loads of features in preceding and I use preceding in some pretty odd ways. So, nobody else ever explores the code paths that I wrote to handle that. And they just break because nobody is even aware that that code path exists really. For instance, setting an early command on the boot command line in DI doesn't work in stretch at the moment because we swapped the order that the preceding was happening and the execution of the early command is tied to one of the preceded packages and that got moved slightly earlier. So, it would go, has it been preceded in a file? Let's try running the early command and then we'll interpret whatever's on the command line. So, it gets preceded, it never gets used. It's not very useful. The other one we found on a similar level is we use in preceding for smaller parts of the actual testing where we're trying to test whether a kernel that's not fully mainline yet can actually provide enough services for DI to run. So, in that kind of situation, we don't care whether it can actually install. No, we don't want it to just install a standard system. Yeah, we're getting somewhere like a password prompt or the, do you want an English prompt in your way? One of the things we found with the preceding is late command is a single command that can't be a list of commands. Do you want to bet? Okay, we need to talk about that because we couldn't... Well, you just make it semi-Carol and separate and you can have as much as you like. Yeah, but when we have a preceded file sent in for us part of the test and we want to add our own late commands onto there, that semi-colon list is actually harder to work out where you put our commands rather than others' commands. Yeah, but you can do it. The real thing is we need to be able to adapt this to live image testing as well. It's basically... Because this isn't preceding, you don't have to know anything about the internals of the thing. You just know what it looks like. So you boot the live image, you look at it, does it seem to have booted? Fair enough, click there. That's it, yeah. So the good thing about it is that you can do this thing where what you're looking for is the user interface talking to you in the way that you want the user interface to talk to you. And if it doesn't do that, it's either because someone's changed the colours or the fonts which you can fix quite quickly. And the person that can fix it doesn't have to be the person that wrote the test. It doesn't have to be the person that wrote the Ruby. So it breaks the job up quite nicely, but it's good. And is it all QEMU? Are you actually calling QEMU to start the actual operations? Ruby is calling QEMU somewhere down there. So we should be able to configure that to be able to test the EFI QEMU with stuff as well? Yeah, I think so. Yeah, so I mean I don't know that much about boot things, so I was looking at DI bugs this morning trying to pick one that I could fix during this lecture. But I don't know enough about firing off. That was potentially one of them, except that I didn't know how to start QEMU. So come along, do that bit. So one thing that would be great is if anybody that likes Ruby would come along and look at the appalling mess that I've made of what was the tiles bits of this and undestroy them. There's something similar going on in Python. I very occasionally write Python code. I don't write Ruby code at all. So my Python and my Ruby are probably appalling. I don't know enough about either of them to know. There are loads of things. Once you've got this thing mostly working, it doesn't even have to work very reliably because Jenkins can be told to run it every four hours. If it works three-quarters of the time, then you get to see a nice traffic light thing where it's sort of working. And that means that the thing that you're testing is probably fine and it's the tests themselves that are flapping, which is great because it means that like when we're doing a point release, the people can be assured that it's installed once after they've... When they're planning to do the release, they can see if they look at the Jenkins thing, they can see that the push that caused them to be ready for doing it has been built, has been installed. So that gives an extra confidence that the thing that they're doing is actually going to work. Obviously, we're not testing everything at the moment. So when bugs come along that do something to the installer which I'm not testing, that's just a prompt to test something else. And we can explore more paths through the thing and over time we should be able to make it so that it's actually quite difficult to get a bug past it. I was talking to Ben Hutchins about getting new kernel pushes to be built and then booting... If we keep our images around that we've got to the point of first boot, then we can use QMU to boot with a more recent kernel without having to do anything to the image because you've got the operating system, you can boot QMU using this image that's outside the image, outside the file system. And then see, well, a pretty good test to just see if it can present you with a login prompt. It's done quite a lot of stuff by then. If you know of things that don't work after that, we can write tests for it and that's great. And the chapter is doing screen for DI. He hasn't really got any rights to upload stuff at the moment. So this is going to... I'm going to be talking to him soon about this. He should be able to make it so that he can do pushes to feature branches of any new dev that he needs to touch to make that work. And it'll get built into a mini ISO by the system without him having to do anything and then test it. So I think that's pretty cool. Also, the screen stuff will mean that we can maybe do the SSH testing and have the backdoor shell thing by just doing, you know, Control-A. Mike, well, what are you saying? I can just repeat it. Were you... what? So which bit of the stack is actually doing the Control-A? Is that Cucumber or is it sickly? Cucumber is... well, it's actually sickly that's pressing the buttons. But if you're using SSH, then you don't need sickly because it would be a pretty stupid thing to have a SSH session running in a headless X terminal and then trying to recognise what was on the screen doing image recognition when the data is actually coming out of the box. So probably doing it in some... I presume Ruby has some sort of expect equivalent library so you could just do send and receive on that. The person to talk to there is Antonio Tocero because he's probably done that. Yeah, okay. Yeah, so I think hopefully we can make it so it's much easier for people to contribute to DI. It's pretty scary trying to change DI at the moment because there's just so many ways you can break things even with one character change because it's busybox shell so it doesn't support all the things that you know for certain have been supported in shell for 20 years. And you can specify options to said that don't exist and it looks fine. You can even run it in your desktop version of busybox and it still works and on DI it won't work. So having some way of just doing the cross check so that you know that you're not doing something silly without having to put yourself in public and ask someone else to use the U-dev that you just built. So, we live on WMQA doing this stuff on the IFTC network. I'm Phil FIL. I'm quite happy to if you've got a thing that you want tested come up with a test because at the moment my biggest problem is that I haven't got useful tests. I think it should be driven by bugs really so rather than coming up with tests that work which if you do that then you write tests which probably won't notice when it breaks. So yeah it's working great. Well actually it's not working it's just you're looking for the outside of the window and the inside of the window is full of nonsense. So if there are things which you think might be testable like this and which there's a bug which we can look for the thing that is the bug and then notice when it's gone away or vice versa. Then I think that's a really good way of writing tests without wasting time writing tests that will never fail. I think that's it. How are we doing? That's not too bad. I wasn't expecting to last that long. We still have around 10 minutes so if you have any questions. So I have some comment from IRC. Oh yeah. Alexandra is watching. Hey hello Alexandra. And she's wearing her Dapkoff Helberg t-shirt. And Matilda is less interested in trying to stuff pencil openers. Thank you very much. More questions? It's more of a thank you for doing it. It's super great and it's innovation that we definitely need. So thank you very much. You should thank Matilda. Because she's the one that's totally destroyed my ability to do anything in more than half hour chunks. So this way I can do a push after 20 minutes and relax rather than not do the push. And then for six months have this cloud hanging over me thinking I really ought to test that stuff. So you know it's taken an enormous amount of time mostly because I can't just like Ruby out of the top of my head. So I have to go and find something to cut and paste it from. And then if you do that half of the things you find are on stack exchange or something which means you can't cut and paste them because the license is interesting. So you have to be inspired by them instead which means you have to do a bit more reading. Yeah so it's taken a while but it's good. When it works, sadly it's not working today but when it really works it's just astonishing because it's so easy to use, the user interface is just good. What we've got at the moment is that if you have any branch that you push into any of the DIY packages and there's no reason to limit this to DIY packages. Any thing on Alioth, anything that you can persuade Holger to point Jenkins at and he's really easy to persuade. So yeah, Patch is very very very welcome. Once you get to the point where Jenkins is actually looking at the repository you just push a branch and it'll get on with it. At the moment we've restricted it to only react to branches that are called P.U. slash something. There's no reason for doing that. It could also be doing the master branches of loads of packages. The resources available are astonishing. Profit bricks have donated loads of hardware for us to use. The main Jenkins machine's got 19 cores or something I think. Last time I looked it's probably about 25 by now. What about storage? I can think of tests that I'm thinking of. We actually need to use Jenkins to build artefacts which then get submitted to other things. Absolutely, those loads of storage. I keep on bumping into limits but I'm doing most of my testing on a little VM and I keep on filling the disk and then we redo it twice as big and I fill the disk. The main one is... We had to move the VM stuff off from Jenkins because there's some minor difference in the CPUs on the hardware which means that it runs 30 times slower on the actual main books than on the one we're using at the moment. That's not just the KVM model, it's not loaded or something? I can't see any difference between anything at all and all the flags are the same but you can see the BIOS character at a time as it's giving you the I'm booting thing. It takes about 23 minutes to get to the first useful prompt in the installer. I can't fake a demo. Is anybody interested in the internal to this stuff or do they want to leave me giggling insanely in my cupboard? This is how the breakpoints work. It's an awful combination of Ruby syntax and English where you can kick it into doing things. What you mean my layout? I think I inherited that from the Tails thing. So it's pretending to be one of those freeform things but then they put it all in quotes so they can loop over it. This is the... So at the moment the romantic execution thing, it doesn't really work but I can get it to run echo hello and then recognise the fact that it said hello which sounds like it's a totally worthless thing to do but actually if you suspend the machine and then resume it you've no idea how soon it's going to come back up. So you can neither look at the screen and hope for the best and what happens then which is great fun to diagnose is that it flashes the suspended screen at you momentarily then it thinks about how the hell to get a hold of the disk for a while. Meanwhile your script has gone, oh I saw the prompt prank which gets thrown away and then your one screen out of sequence and it all goes wrong. So it's actually quite useful to have a thing that if you type echo hello at it it says hello because you can keep on doing that at the not quite unsuspended machine and when it finally comes back it replies with a hello and then you can carry on with your script. So even the really brain damaged version of that is useful if I had someone that was interested in that weird little niche in Ruby then we could probably make it a lot better. By top and tailing all commands with some strings to recognise and writing it's difficult to do though because it's busybox shell and I'm trying to do it without actually modifying the image so you're going to have to survive that broken shell long enough to inject a real command that you can use into it and notice that you've really done it and then you can run that command and then we can start doing the thing that the tales folk do where you say I'd like you to run this command as a user but it's not very useful in DI that bit but I wanted you to run this command and give me the output in a particular format or whatever. Yeah, I was going to show you a movie. I'll show you a movie for the last little bit. I was trying to find that on jingas.net. What's the path to that view? What's the URL to that view? I was trying to find it in jingas.net. Shall I paste it into our RC? This is a machine that's not really in public use but you're welcome to look at it. Where are we? Where do you want it? There you go. Nope, you wouldn't be able to find that would you? Yeah, it's just one of the little VMs that's been set up on profit bricks and it's got a copy of Jenkins on it because that way I can thoroughly trash Jenkins and add more plug-ins and things like that. So somewhere on there there's the mini ISO job. I can't have a look. I can't recognise it when it's all blown up. In there you see GUI, LXDE, LXDE and MPEG. This is a recording of a previous install. It tabs down to here and then types a load of shit onto the command line to get the early command to work. In theory to change the... It tends to blank the screen which is really annoying. Which is why I couldn't actually test the recent stuff because during the downloading thousands of packages thing it does five minutes of that and then the screen goes away. You don't see anything anymore. Although now I've got a loop that keeps on pressing F3 or something which the GUI seems not to mind you pressing F3 all the time. The nice thing about this is that you get an email saying it's all broken and rather than having to install it yourself you can fast forward through it and then you can get to the end. It's pretty cute. This is the first reboot going on and then you notice that's taking a long time. I thought system D was going to be quicker. I'm pretty sure there's nothing to do with system D so it got five seconds into the boot and now it's... There we go. So a couple of minutes in it's gone sort of bang in some way and then we have another minute. So anybody that knows why this is happening in VMs under stretch and then it does this. That's lovely, isn't it? I think it's something to do with... The first long pause I think is something to do with the graphics. There's something with the graphics and the way it happens inside when you're running KVM inside KVM and the combination of those two things this is why you don't actually see it in real installs but it'd be quite nice to fix because this makes the test when you've generated all the images you've run the thing to the end and then you snapshot it. If you run that test again it should do it from the last snapshot which takes about 12 minutes at the moment because it's looking at this. It should take about 20 seconds to boot three different desktops. It's booting. And then, eventually, that's the screen switch. Lovely. And then very briefly you'll see a login prompt. Then it goes, yep, that's why. Or was it so briefly that we didn't see it? It recognises this bit and that's your first boot. All good. So that counts as a success and that's why you end up with... That scenario that I showed you before is all here and it's filled in a little table and the fact that there are no errors around the place indicates that it worked and you've got three scenarios, all the steps and it tells you what happened. So... What? Time's up. Okay, cheers.