Shift Left: Continuous Integration Testing with Cloud Build (Cloud Next '19)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[MUSIC PLAYING] DAVE STANKE: All right, so my name is Dave Stanke. I'm part of the Developer Relations team here at Google. And with me is Christopher Sanson. He's the product manager for Cloud Build. He'll be up a little later. And that character up in the top right, that's Billy the Builder Bee, and she'll be helping us out later on. So we're shifting left. What does that mean? It means to incorporate critical processes early in the software development cycle. What does that mean? Well, we can usually model a software development process as a left to right flow, where we go from code, through some transformations, see if it's any good, ship it, and then operate, monitor on it, as it's live. And we model this as a left to right flow. Shifting left means moving the important steps of validation and quality control earlier in the process, closer to the left. But of course, software development doesn't happen in a single stream. We usually have lots of these flows. And in a traditional process, every developer or team progresses independently. They're focused on writing more and more code, until at the last minute, everything collides. And all at once, all of these bits are meeting for the first time. And we're hoping for a quick, thumbs up, let's ship it. But when you have a whole bunch of code, it's strangers to each other. And you shove them all in a room at once, they might not get along. And so it's more likely that we're going to have merge conflicts. We're going to have terrible security holes. We're going to have incompatibilities between some systems. And this is why in a traditional waterfall-style development process, you often have huge, lengthy merge times. You often have long lead times. And you often have terrible weeks before and after a major release. So we shift left. We move processes earlier to get earlier feedback on small checks all along the way. So if you take two small pieces and you validate each of them independently, and then when they combine, the only thing we actually have to test then is what arises between the connections between them. So what are we shifting left? Well, you can shift left lots of things. First off, you can shift your merges left. And this is continuous integration in the original meaning-- that instead of having long-lived branches that hang out on a developer's machine for a long time, we're going to merge at least once a day, preferably more often. And each one of those merges is then small, relatively pain-free. And we don't have "the merge" that everyone dreads. We can also shift left on security. So a lot of times, traditionally, we put together a big software release. And then just before we ship, we go to the security people and we're like, it's good, right? Give us a thumbs up. And they say, slow down. Well, we can do a lot better if we do security validation earlier and oftener. So within code, you can do things like automated fuzz testing to make sure that your code actually has some protection. You can test individual components, look at open source packages you might be using, using vulnerability analysis, and generally have affirmation that your code is pretty secure all along the way. And at the end, you're only validating, again, that very outer perimeter of the code. And then you can shift left on testing. And this is what we're going to really dig into-- testing early and often. And why do we want to test early? To catch bugs early. I'd bet a lot of folks here are familiar with the research that's been done by NIST and IBM talking about how finding a bug in development costs way less time and energy than finding one in production. The numbers I've heard are anywhere from 6x, to 30x, to 100x. But certainly, you'd rather catch the bug early. Why? Why is it so much cheaper? Well, I think there's a couple of reasons. One, if you catch it early, it hasn't had time to have downstream effects. The other system components aren't aware of that bug. They're not working around that bug, as they sometimes do. And two, if you catch a bug while a developer's still working on that process, it's still in their mind. There's still in that flow, and so they don't have to rehydrate and reconstruct, what was I thinking when I wrote that code with the bug in it? So for these reasons, it's really great to fix our bugs early and be testing early. Oh, and one quick bit of science here. From the State of DevOps Report-- and actually, I believe there's a card on every one of your seats encouraging you to participate-- the State of DevOps Report does analysis finding out what practices are done by teams that have the most software quality. And they find that continuous testing predicts continuous delivery, which predicts delivery performance-- how often we ship, and how fast we get from code to live-- and availability, how much of the time our services are available. All right, so let's look at testing and how we can shift left on it. First of all, some definitions. So we often talk about testing as the testing hierarchy. We start at the bottom with unit tests. And unit tests, of course, are the foundation. Unit tests are where we test small functionality of our code, kind of within the frameworks of our code. And honestly, these are a mostly solved problem-- maybe. But most modern frameworks have unit testing built in. It generally can be run pretty quickly as part of your build and CI process. Integration testing is when we test multiple components together and when we make sure that, when these things are actually running, like in production, that when they work together, they don't all of a sudden fall apart. This one worked. That one worked. But the application doesn't work until you have both of them. And on top that we've end-to-end testing, which means usually running a multi-step process against a composed application. There's kind of a fuzzy line between integration testing and end-to-end testing. And the terms are sometimes used interchangeably. Now, this diagram might look like a tall, intimidating icy mountain, but we're going to show you that it's not that hard to scale to the pinnacle of testing. Today's focus is on integration testing, but everything we're looking at can be used for E2E testing, as well. So our goals for integration testing-- we want high fidelity, high isolation, high scalability, appropriate ephemerality. And we always like speed and low cost. We're not going to get all the way, but these are an aspiration to shoot for. I'm going to show you some ways that we can get close. So first of all, fidelity. Now, when we do integration testing, we start by creating a system under test. That's the environment that we're going to test against. We're not going to test against prod, right? And so we create a simulation, effectively. And our goal here is fidelity. How similar is that system under test to the production system? The closer we get, the more assured we are that we're going to have tests that reflect what reality is going to be like, what our users are going to experience. And we're generally not going be able to create a full production environment for each test, although we'll challenge that later on. So we're going to run against a scaled-down version of that full ecosystem and aim to make it as predictive as possible. Isolation-- this means that each test is running completely separate from the others. They're not going to stomp on each other to compete for processes, CPU, memory, disk space, whatever. And they also don't connect to the same external resources. If you have a shared database or a prod API, even if it's read-only, it's entirely possible for a runaway read to block everyone else from using it. Isolation also has to do with security, so we want to configure all of the resources we use within tests to not have public visibility. The last thing we want is for someone to corrupt our tests or somehow give us bad data that then sneaks into prod somehow, or run a bitcoin miner on our testing infrastructure. And then scalability-- of course, we want big. How many tests can we run at a time? Ideally, every developer can kick off all of their tests at the same time. We don't want developers waiting while their tests are queued up behind their colleagues. Remember that flow we discussed? Keep the developers going. And this means we want to be able to scale the test infrastructure elastically and parallelize all of our tests. So that, of course, is a great fit for cloud infrastructure. And then ephemerality, which means, how long does that test infrastructure hang around after we're done doing our tests? Ideally, it lasts just until the test is over. And then it's gone, right? We don't want to pay for it. And then we optimize the ephemeral nature of the test. But the thing is, if the test gets torn down immediately, then we don't have access to go debug what happened inside that test environment. Now of course, best practices, you should not be SSH-ing into your prod machines. But for a test machine, you can learn a lot from a failed test by going in and saying, well, what's going on? What process is there? What actual data got written into that file? Oh, it's not what I expected. So the best of ephemerality means that the system lasts exactly as long as I need it and not any longer. And of course, speed is good. We like fast. This is important both so that we can keep our developers productive and also so we can increase our mean time to deploy-- decrease, rather. Fast is better than slow. And finally, affordability-- developer time is expensive. And generally, it's a good use of money to give infrastructure to your developers for their tests, but it's always going to be a trade-off. And you certainly don't want to pay more for your testing than it's worth for the sake of your production environment. All right, now I'm going to kick off a quick demo. There we go. All right, so what I'm going to do here is I'm going to start off a series of four tests. And I'm not going to explain them just yet, I'm just going to get them going. But I'm in my editor here, and I'm running this as a GCloud submit command. Of course, you can also run this from a trigger, as well. So we'll kick that off. And we will head to our UI, and we'll be able to see. This is the Cloud console, and we're going to look at the progress. And we're just getting started on it. And back to the slides, please. And now, Christopher's going to come up, talk to us a little about what testing is really like and how close we get to those goals. CHRISTOPHER SANSON: All right. Thanks, Dave. Hey, everyone. So as Dave mentioned, my name is Christopher. I'm a product manager at Google working on Cloud Build, which gives you a bit of a hint of what I might be talking about. But before we get into it, one thing we hear from customers all the time is, you come to an event like this, you read blogs, you read up on the best practices, and it's really inspiring. You hear about things like shift left, things like DevOps, SRE, infrastructure as code. But when we talk to customers in sort of back and reality is that, look, this is great, but this is kind of like flying cars. Like we get it, but it's so far from where we are today and our day-to-day reality. We need help both with tooling and operations and processes to help us get to where we want to be. So I want to take a quick minute to look at some test patterns and test strategies that we see in the real world and what's happening when things like shift left, I think, are reasonably accepted as best practices. So I think the first test that anyone ever runs is the build itself. Every application starts with compiling code, running a build. And you iterate, and you test your code, and you hack on it, and you debug. And then eventually, finally, the build is green. And so that's, I think, often as far as a lot of different applications ever go. If the build is green, my app is green, right? But obviously in modern architectures, with things like microservices and external dependencies, just because your build is green really gives you no indication that your ultimate application is going to run correctly. There's a lot of external dependencies that can change out from underneath you while you're working. Other APIs can shift. And so you really need to actually test and validate that the way that your application works isn't just complete in and of itself, but actually in the way that it talks to other services. So the next thing we see a lot of people do is, OK, the build is green, and they start adding quality gates. So these are static analysis tools, either commercial, like Codecov or Coverty, as well as open source things, like JSHint and JSLint, things like that. And quality gates are really great. They are very fast. They're very cheap, and they give you a really good indication of code quality. They could do everything from validating against your style guide, linting, giving you a sense of how much code coverage you have. The challenge though, is-- for anyone that's looked ahead, if you look at the unit test that we wrote, that unit test isn't really going to help you very much. All it's really going to do is just get your code coverage up to 80% so you can be allowed to like merge your commit. So what we find is, quality gates are really helpful and really powerful for indicating that your code is probably going to work, but it doesn't actually do anything to verify that your code will work. So after you've had quality gates-- this is my personal favorite test strategy and one I've often employed. I like to call them Humpty-Dumpty tests. This is where you don't actually write any tests till after the failure occurs. Something will go down in prod-- you'll have an outage. Your users will talk to you and say, hey, this is down. You figure out the recalls, you submit a quick fix, and then you go back and write test coverage. Obviously, this is a big reality of software development. You're not going to catch everything. But I think it's sort of obvious you don't really want your users to be your QA. You want to test and capture these things before they reach users. By the way, I wanted to give a shout-out to our Illustrator, Tracy. This is maybe my favorite illustration that I've ever had at a talk I've given. We were like, well, the idea is, it's Humpty Dumpty. It breaks. And this is what she came up with, so shout-out to Tracy. And the last thing is classic, almost cliched at this point. It's sort of, well, it worked on my machine. So we ran a survey on Twitter. We asked people in microservice architectures, where's the first point in time that you actually test your app, versus the other services it interacts with? And this number was actually a lot higher than we thought. So 43% of developers were actually testing it in their local machine before pushing to prod. So this is actually encouraging, but this often leads to the kind of, it worked on my machine, the classic failure mode where you throw it over the wall to the deployment or ops team. And then there's this back and forth of blame game of like, well, it worked for me, but it's not working for me, et cetera. This happens because they're different versions, there's different OSes, there's different file path dependencies. Just because you run a test locally doesn't really give you a ton of confidence that it's going to run either in your CI system or in production. So why are these some of the patterns that we see? And we're not trying to present these as anti-patterns, right? Like, if something goes down, you should write a test to cover it for the next time. You should do quality gates. You should be testing locally. But I think what we found is that, when it gets to things like integration testing, it's just not that easy. It's not that easy to do. There's a lot of friction. Two of some of the primary reasons, I think, just as a developer myself, is that, the last thing you want to do as a developer is to lose flow, is to get out of the context and have to wait for a long build. And if you are using a hosted CI service that you pay per concurrency, or if you're self-hosting your infrastructure and you're responsible for scaling it up and down, it can lead to long build times, long queue times. So as a developer, you find your own workarounds. You test things locally. You write fewer tests. You test later on in the process. So this is where some of the tooling can really empower developers to lower the bar of entry for testing things earlier on in the process. And the other aspect is just environment management. So it's simply just somewhat difficult, often, in different situations, to provision infrastructure, manage that infrastructure, spin up databases and spin them down, things like that. So which leads us to Cloud Build. So Cloud Build, if you've been to the other talks, you may have heard of. If you're a GCB customer, you may be using currently. But if you're not familiar with it, Cloud Build is a hosted CI/CD service on GCP for building, testing, and deploying applications. It's generally available. It launched about two years ago, originally called Container Builder. Last year at Next, we announced it as Cloud Build, as it covered a broader spectrum of CI/CD use cases. And I think one of the biggest things that we hear people really like about it is that it's serverless, for whatever that word may mean to you. It's a fully managed infrastructure. And you pay for what you use, so you pay per build minute. So if you have a huge CI infrastructure that's idle most of the time, you don't really have to worry about that. And the last thing-- one of the announcements this week is, Cloud Build is adding support for hybrid and multi-cloud workloads. So it's currently in Alpha. It's a new feature called, Custom Workers. But it's going to let you use Cloud Build with a VPC to connect to your on-prem private networks. So if you have a self-hosted repository or you're deploying to a runtime like GKE on-prem, Cloud Build is going to be able to work with managed infrastructure with services and resources behind your firewall. So let's take a look real quick-- so how Cloud Build works, there is a build config file that's in YAML, of course. And in that, you define what you want Cloud Build to do for you. So you define a series of build steps. And in that config, you could do things like define your dependency graph, environment variables. It integrates with KMS, so you can do secret management, as well as the artifacts that you want to build. So what this looks like in your pipeline is, you have often source code in your repository. You can set up automated build triggers so that when you commit to your repo based on branch, or tag, or pull request, it will kick off a Cloud Build. And in that build, you'll run a series of build steps. And so build steps are like Jenkins stages, or GitHub actions, or any sort of CI systems concept of jobs or tasks. And each build step is a container in the Cloud Build world. So anything that can be containerized can be run as a build step. And at the end of your build, there's some outputs. There's a status, usually pass/fail, any artifacts that were created, and then any deployments that were made, if you're using it for continuous delivery. So what are some common build steps? We have a whole bunch of supported builder images out-of-the-box, things like Docker Build, Maven Build. There's a GCloud one. So any command with the Cloud SDK you can run locally, you can run in a hosted cloud environment with Cloud Build. And the last one is you could bring your own container. So as I mentioned, we have a bunch of predefined ones for the most popular tooling. But if you have custom tooling, custom versions you want to use, any sort of arbitrary scripts you want to run, if you could containerize that, then Cloud Build can execute it for you in a hosted environment. So if you start to think about the possibilities there, what that means is people are often like, well, is Cloud Build just for building things? And answer's, well, sort of yes, but it could do a lot more. It could be used for anything that can run inside of a container. So in the context of integration testing-- which Dave is going to show us a little bit more tactically how this works in practice-- you could use some of the common tools. So if you're using Docker Compose, you can run a Docker Compose step, spin up services in the background, like databases, run tests against that, all during your CI process. It has support for things like terraform and kubectl. And then you can run arbitrary scripts, as well. So if you have existing tests that are shell scripts or Python scripts that you want to run, you can just simply wrap those up in a Docker file and run that, as well. So just to wrap up before I hand it off-- so why Cloud Build? I think first and foremost, it's serverless. It handles a lot of the boring stuff for you. It scales up and down. You pay for what you use. And it's isolated. So every build step runs inside of a container, and every build runs inside of a VM. So a VM is your isolation boundary, and it's ephemeral. So we have workers ready to go to run your jobs. And at the end of a build, we'll spin down the VM. So anything that you may have spun up during the time sort of goes away. You don't really have to worry about managing state through persistent environments, things like that. And the last is the flexibility. So we give you a lot of the out-of-the-box tools that are the most common use cases. But with things like tests, a lot of teams have their own processes, have their own tooling that they wrote around this. And really, Cloud Build allows you to run anything that, more or less, you could run. And so with that I'm going to hand it back to Dave to show us this in action a little bit more. DAVE STANKE: Thank you, Christopher. All right, so let's take a look at how we can use Cloud Build to actually do some of this cool integration testing stuff. So I'm going to show you a demo that includes this sample application. This is a simplistic version of a microservice application-- just two tiers. We've got a web app that's running Node.js and a DB that's MySQL. But of course, as engineers, we know that the only numbers are 0, 1, and infinity, which means this has an infinite number of microservices. You can definitely scale up these techniques. And this just renders a cloud cookie shop app. And it runs inside Kubernetes. You can use these techniques for any kind of integration testing. But here, we're focused on a microservice app with the deployed target Kubernetes. Integration test flow-- first, we're going to build our containers. We have the web and the db. Then we're going to provision a test environment, deploy the web and the db containers to it. So now, we have a system under test there. And we're going to run a test against it. And so again, this isn't an E2E test. this is just a point-in-time test, but it does exercise both of the layers of the application. It's just going to curl the endpoint and grep for a particular string. This is a cookie shop, so what it's grepping for is the words chocolate chip. That's a success, you know, clearly. If it passes, then we're good. We don't need that environment anymore, and we'll deprovision it. And if it doesn't pass, the test is going to end and fail there. So most the time then, the environment's going to stay around so we can debug it, though there's some trade-offs there that I'm going to show you. Now, in my experience, the hard part of all this is the provisioning. There are a lot of different ways to do it, a lot of trade-offs among the different ways to do it. So we're going to look at different mechanisms, different techniques for provisioning and deprovisioning a system under test. So the first one we're going to look at is Docker Compose. Now, Docker Compose is basically a wrapper around Docker. If you've ever run a Docker Container with a dash d, you're creating a service that sticks around. Docker Compose will spin up multiple of those and let them network in between each other. And in Cloud Build, the way this happens is that when you run Docker Compose within Cloud Build-- and there's a supported builder for Docker Compose that lets you clone that and run that into your project. And so the way that works is that the builder instantiates these containers that you're creating, this composed network, as sister containers. They share the same network as the build steps of your build so you could interconnect between them. And it's exposed on a Docker network called the Cloud Build network, and then other steps can talk to them. So here's the flow. We start from our checkout from Git. The gray box here represents the boundary of Cloud Build. That's that security boundary that Christopher was talking about where nothing can get in or out without you expressly doing it. And it's actually out only. And so the steps here are, we're going to build, run some unit tests. And then we use Docker Compose to create those sister containers. And then we have our integration test, which is just a shell script, asking whether it succeeded or not. And our build is over. So the pros of this is that it's fully ephemeral. Everything took place inside that Cloud Build environment. And when the test is over, everything gets torn down. You don't pay for anything after the test is over, so there's no chance that you're going to orphan those resources and be paying for them after a long time. And for that reason, it's cost-effective. You're only paying for that Cloud Build run, which is billed by the minute. And there's also a generous free tier, so you can get a lot of mileage out of this. Now the cons are, it's always ephemeral. You can't get back in afterwards and go poke around inside the Docker Compose environment. I've done things where I write a bunch of logs somewhere, and it kind of works. But you're still a lot of spelunking to go and figure out, well, what happened in there? So that's not necessarily ideal. Limited fidelity-- because we're not going to use Docker Compose as our actual production runtime. It's generally not going to be your best choice for that. And so therefore, it's not exactly the same behaviors. You don't know if what works here is really going to work on prod. There are some funny things about startup order. With Docker Compose, when you start up the containers, they all just start. And if they fail to start, they all just fail. And so when I was working on this, I had the web app would start up faster than the DB. The web app couldn't find the DB, and it failed. I had to do some kind of funky workaround to make it so that it would hang around until the database came up. And in fact, Docker Compose used to have support for health checks and removed those deliberately, because it's not designed to be a production runtime. And finally, the one that I like the least here is the multiple configs. You can't use the same config for a Docker Compose environment as for your production Kubernetes environment. And inevitably, you're going to have drift between those. So let's try again-- method 2. So in this case, we're going to use a GKE staging cluster and deploy all of our tests to that same cluster. So that sounds like a lot of things stomping on each other, but we're going to isolate via namespaces. And if you're not familiar, a namespace in Kubernetes, it's an isolation mechanism where you scope a number of resources to a defined namespace. Now, namespaces can talk to each other, but you have to do that deliberately. So by default, everything in a namespace thinks that it's in its own bubble. And unless you work hard to undo this, they're going to be isolated together. In Cloud Build, the way we're going to do that is, on each build, we're going to create a uniquely named namespace, deploy those things, test it. And then on success, we'll destroy that namespace. Nice thing about namespace, if you destroy the namespace, everything in it wipes away along with it. So in this case, what you'll see here is that we do our build on our unit tests. And then we're going to use kubectl to deploy a namespace into our standing staging cluster. And you see, that's outside of the Cloud Build network and, therefore, has a different level of ephemerality. Then we run our test. If we get to the end, kubectl's going to destroy that namespace and all the resources in it. If we don't get to the end, that last step isn't going to run, which means that namespace is going to hang around so we can use any tools that we can operate against the cluster on to go look into those containers, look at their disks, et cetera. So the pros of this-- excellent fidelity, especially if your prod happens to be running on GKE. And I hope you've heard some things this week that have helped you think that maybe that's a good idea. Easy tear-down-- delete the namespace, and everything's gone. And we have that ephemerality that we're looking for that, on success, it disappears. On failure, it hangs around to go debug. Cons-- imperfect installation. Now, it's unlikely, but it's possible that one of your tests has runaway disk usage or runaway memory. Messes up another test that's running at the same time on the same cluster-- unlikely. But something that is more likely to be a challenge is that you can't test a cluster-wide resource. So for example, the Agones project, which has presentations this week, is the cool open source framework for running multi-player games on Kubernetes. The way it works is it creates custom resource definitions. And custom resource definitions are cluster-wide. So they can't test different versions of a CRD all in one cluster. Also, if you wanted to validate something against different versions of Kubernetes, for example-- well, you can't have one cluster that has multiple versions. The other problem is that you may have orphaned forces that, if you fail a test and you don't bother going in to look at that namespace that didn't get deleted, it's just going to hang around. Not a huge impact. Having a namespace with no activity isn't a major problem. But you probably would want to have some sort of a cleanup script that runs once a week or something and just deletes everything that everyone forgot about. So now, if we wanted to get absolute isolation, we can try using a Kubernetes cluster for each test. And what we're going to do here is we're going create a Kubernetes cluster in a VM so that each test has its own completely isolated environment, its own VM that it's operating in. And to do that, we're going to provision that VM with Terraform, and we're going to install a single-node Kubernetes application. There are several of these-- MicroK8s, Minikube. There's one called K3S. These are all compliant Kubernetes servers that run on a single node. And in order to offset some of the ephemerality issues here, we're going to use a self-destructing VM. So a self-destructing VM is one that, if you forget about it, it won't just hang around and cost you money forever. Instead, it's built in with a timer mechanism. And after a certain amount of time, if no one touches it, it will delete itself. If you're interested in making your own self-destructing VMs-- it's kind of fun-- check out that bit.ly link. So with this one, it's similar to that GKE one, except this VM is being provisioned on-the-fly and has Kubernetes or a Kubernetes-compliant server in it. We're going to deploy our application to that Kubernetes, test it. And at the end, we're going to use Terraform to tear it down. And again, if it doesn't tear down automatically because of a success, it instead-- you can go and play with it for a while. And it has an expiration date. It could be two hours, two days, whatever-- it'll delete itself. So what's good about this one? Well, perfect isolation, near-perfect fidelity. Again, these non-Kubernetes Kubernetes, they are actually certified compliant as being Kubernetes runtimes. But who knows? Maybe they're not exactly the same thing. You can test those cluster-level resources. And we've got that ephemerality that we wanted. Downside, it's still not exactly GKE. And also, there's the possibility that these VMs hang around longer than you want, even if they have an expiration. All right, finally, when I was working on this stuff, people like Christopher kept asking me, well, why don't you just create a GKE cluster for every one? And I said, boy, that sounds really expensive and slow. But of course, it's possible. And by doing that, you of course get all the fidelity, all the isolation. You can create the entire production environment. You could even, if you wanted to, clone in a database or other things from production so that every single test has its own GKE. And it can be done. There's APIs for it. And I'm actually going to show you as part of the test how that works. So let's check on that demo. Let's see. Here we go. So what I did when I kicked off that build back in my IDE is, I ran what I call a meta CI. This is a Cloud Build invocation that kicks off other Cloud Build invocations. And each one of those is one of these testing mechanisms. In every case, we're testing the exact same application, running the exact same test script on it. But we're instantiating and tearing down our test environment in different ways. So we have all four of the methods I just showed you. And if we look into the UI, we'll see that they all completed. And they all returned the same result, but very different amounts of time. The Docker Compose was very quick, because it didn't have to reach to any external resources. But GKE cluster per test? Pretty slow, but perfect fidelity. And the other ones are somewhere in between. So what's the right choice for something that you're going to do? It really depends on what you're doing. Can we switch back to the slides, please? So in summary, we took a look at a number of different mechanisms for spinning up and testing against a microservice production environment. And you can see they all have pros and cons. For example, with Docker Compose, it scales really big. You don't have any extra resources. That shared staging Kubernetes is pretty good all around, but you don't necessarily have perfect isolation. A Kubernetes per test should scale. But at some point, you're probably going to hit some quota limits on IPs and things. I haven't tried running tens of thousands of those, though. It probably would be kind of fun. All in all, when I was working on this, folks were asking me, well, what's the right one? And I said, oh, it all depends. It doesn't matter what you're doing. But really on balance for most use cases, I think this is a really good choice, this shared Kubernetes environment. If you turn on auto-scaling, it's going to scale up and scale down to meet the needs of your developers. They're not going to have standing resources beyond a minimum number of nodes over the weekend. You've got all of that great fidelity. It's fast. And the isolation is probably good enough for most workloads. If it's not quite there, maybe you add one of those more intense things as a final check. We can do more. We can use these same kind of methods to do deeper end-to-end testing-- a scripted test that creates an order, puts something in a shopping cart, buys some cookies. We could do mobile web testing. There's a service, called Firebase Test Labs, that Google provides to test against Android devices and iOS. And we could use external resources. So say for example we wanted to spin up a dedicated Cloud SQL per test, we could do that. So this application and all of these test methods are available on GitHub. I encourage you to download it, give it a try. Pull requests are welcome. Feedback is welcome. Speaking of feedback-- wait, I'll get to that in a second. Speaking of feedback, tweet at me. Here's my Twitter. I'd love to hear from you, what you're up to, how you're approaching problems like this. Christopher doesn't really do Twitter. So if you want to get a personalized response from him, just go to Cloud Build, and go to that feedback link, and he'll write back to you. It's like a stationary calligraphy. It's great. I kid. But it is actually a really responsive team. And they absolutely want to hear your feedback. And they're absolutely listening. [MUSIC PLAYING]
Info
Channel: Google Cloud Tech
Views: 7,209
Rating: undefined out of 5
Keywords: type: Conference Talk (Full production);, pr_pr: Google Cloud Next, purpose: Educate
Id: pqCq24aEka4
Channel Id: undefined
Length: 35min 47sec (2147 seconds)
Published: Thu Apr 11 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.