 Hello everyone, so I am here with Ergo and Laurent. They will be presenting revolutionizing API testing and mocking with test containers modules. So I will leave it to them to continue with the session. Good luck. Thank you. Thank you. Thank you everyone and welcome to this session. We are really happy to be here and I hope you're enjoying the session, you're enjoying the whole days and I think you will like this if you are doing APIs. You have been struggling with mocking testing. I think this is something that certainly can help you out. So Laurent, do you want to do some introductions? Yes, let me start. So first, thank you, Ergo, for inviting me on stage. I am quite happy to do this kind of event with you. It's always a pleasure. So a few words on who I am before starting. So basically, I'm an open source fanboy and I was working at Red Hat previously and I'm one of the co-founder of this Mycrocs open source project we are going to talk about in a few minutes. So I used to be a cloud native architect until very recently, worked at Red Hat, worked in financial services also. And yes, basically I've got a strong background in designing distributed systems, designing API programs and the underlying infrastructure. So could it be Kubernetes or OpenShift as well? And on a personal note, yes, I like to raise kids. I'm a governor and you'll see that I love pastries. Exactly. And I think we share that love for pastries. So a little bit more about me. My name is Hugo, I'm part of the Red Hat team. That is working currently on what we used to call middleware, now application development BU. I'm a Mexican based currently in the Greater Boston area in Massachusetts in the United States. Here is my tutor handler. If you want to continue the conversation later, if you don't feel comfortable with the chat, you can always ping me. And as Laurent, I'm an open source advocate. I love to contribute to open source, been able to be part of this like we are doing with Mycrocs. And I specialize mostly on APIs in general, even driven APIs, asynchronous APIs, everything related to that. On the personal note, yeah, I also like pastries and any kind of pastries, Mexican pastries are good pastries too. But also history, travel, and I consider myself a food enthusiast. So I'm very happy to be here and to be able to share with you. So Laurent, are you ready to get started? Yeah, ready to get started. Yeah, ready to get started. Let's go for it. Okay, so before diving in, I'd like to highlight why this topic is of importance. And it's because we are in the era of distributed systems. And I'm pretty sure that many of you are already dealing with this kind of architecture. So you can call it microservice, mining service, SOE, whatever. It's a distributed system. And how many times have you ever heard or said that every time you're touching a component somewhere, you break something, or you hand up building some big release train and releasing everything together. And finally, you hand up with the situation where all the components everywhere have the same version. So you finally ended up with distributed monoliths. You go maybe if you can, next slide. Yes, same version everywhere. So it's not just because you're distributed but you're decoupled. It's not just a matter of starting with the deleter. And in fact, if you can go to the next slide, you go, what you really want to achieve is this kind of situation when you have components with different life cycles and different versions. And when you are able to develop, to validate and to release everything in isolation. So that's really the true benefits we want from this kind of architecture. And you'll see that testing, contract testings are really, really, really important. There are great methods to get a high level of confidence that will allow you to reach this kind of situation and to unlock the true potential of distributed and decoupled architecture. So really, we are going to put the emphasis on testing, integration testing or contract testing in the 40 minutes to come. So you go, maybe you can just start diving in. Yes, as you were saying, the idea of microservices to be able to work with different versions, to be able to have distributed architecture but also being able to deploy applications and being able to have them working all together. So the main topic for doing this is through integration testing. So basically we're meaning that we have testing as unit testing where we can check each one of our methods and functions and parts of the code. But also we have a point that we need to integrate and being able to connect and try and test these kinds of integrations with other systems and services. It could be an API, it could be a message broker, it could be a database, it could be a different type of systems. So the way to be able to do this usually involves an integration testing environment. And what it means, it's that you will need to have a shared instances that are running that everyone will be using to be able to run those applications, being able to go for those resources. Or it means that you will need to have a local replication of the production environment or at least something that it looks like production environment in your own laptop. Maybe for some lightweight services, it could be something doable. But sometimes when you're talking about big databases or you need infrastructure like three nodes, replica of a Kafka cluster and so on, it comes complicated. Another approach is to try to do in-memory solutions. But that's a little bit limited because you won't be able to have certain features that are gonna be present in the real environments. So that's also an option that it's available but sometimes looks complicated. And finally, one of the latest trends is to be able to use something like Docker compose. So you are able then to reproduce and start a local version of certain environments. But again, it's a local installation. It's easier than having to install a full database on your laptop, but still it's something that you will need to run with the same resources as the application that you are crying. So this is a series of challenges that we have when working with this. So instead of going all the way to the shared environment, we have this practice that we have seen raised in the past that it's focusing on shifting left. And basically the idea of shifting left is that we are gonna be able to work with our microservices, with our applications and then being able to consume those services. But in a way that we are getting closer to the application where we are able to have all those different stacks, being able to connect to them from Node.js applications, Java applications and being able to validate and having a testing environment created and provisioning at the moment that we are executing the tests locally. So basically helps us out to be able to reproduce this when we are as close as possible to the code generation or the coding phase. So we are able to avoid getting integration builds and then missing or finding that there are some challenges or that something is missing later in the phase of the testing. Now, however, as we were saying, being able to reproduce those environments on the developer laptop, it's not easy. It is a little bit more complicated. So what we can do is that we can get benefits of some frameworks and libraries that we have available and that we can use for that. One of these options, it's used a series of frameworks called test containers. So test containers were created just after Docker was launched and initially it was focusing on being able to create these testing environments for, or basically environments for able to run tests. And the benefit of this is that we can then create these environments and also manage their lifecycle of the environments. It is actually a library, but it has been ported to multiple languages. The Java version is one of the oldest, but there are other more that have been provided by the creators of this containers and also some others that were contributed from the community to be able to cover more languages. Basically how it works is that it works with Docker. So the common dependencies for our tests are being managed by this library, this API, that it's available to connect with Docker and be able to start some of the containers. But it also helps us to download and run Docker files so we are able to then generate an environment that is more similar to what we are gonna be experiencing in the deployment of our application. It helps you to manage the lifecycle, the advanced networking, and this is very easy to use. So that's why it's getting a lot of traction and a lot of log. And here's the GitHub repo if you want to go there and try it if they have been actually been acquired by Docker. So that's a very recent news in the last day. So very interesting things. And the last point that I was mentioning related to the lifecycle is important because if you are not using test containers and you are still starting your containers in a manual way, you need to manage the lifecycle independently. That means that you will need to run a script so being able to be sure that the environment it's clean up and it's been start up at the exact time when we're using the framework of test containers, that is something that we can directly do during the different code phases of our code and our tests. So we have the before test where we are gonna be sending the instructions to be able to start our container, to do some initialization or clean up of the environment. During the test, we will have the container running. We will be able to then interact with the container either through the DCP socket or an HTTP endpoint, depending if you are using a database, like this measure where we are referring to phosphorus, but also we can do something like, we are gonna see APIs to be able to interact and communicate for testing and other capabilities provided by the container. And finally, when we have finished our tests, successfully, hopefully, if not, we're gonna see them crash and burn. We need to clean up the environment, right? We need to tear down the containers that we were using on all the things that were there to be able to be sure that there's nothing left behind and we can then restart again in a new way. And who's providing those test containers? They're provided by them? Well, no, they have something that they call modules. And these modules are part of the test container's ecosystem, but are provided either by the vendor or are being provided by some members of the community. And the idea is basically that you will have a pre-configured set of instructions to set up certain, aspects of these resources, so middleware components or in this case, something like macro. So they have a complete set of modules, that you can search by the language that it's supported, Go, Java, Node.js, Python, et cetera. And also you can filter by the official modules where you can find that there's different partners and vendors that have been working together with Atomic Jar, who's behind test containers, to be able to guarantee that the modules are compliant with at least some of the guidelines from the guys from test containers. And, well, MicroX is actually one of those examples. But why? Let's go deeper on that. And it's because it benefits from what I was saying was one of the first languages that were implemented with test containers. So it's a Java one. It was created seven years ago, pretty much after Docker API was released, using the Docker Java API. And the interesting thing here is that you can use the framework from test containers to be able to integrate with your year unit and all that kind of frameworks to be able to be part of the lifecycle of your test, your test, as well as being able to be incorporated with test containers. It's great if you want to run anything or you're working and testing anything that can be run as a container. So containers, test containers, Java, it's one of the foundations of how what we are going to be covering today. However, there's more than that. So because that's just a simple way to start containers. But then comes MicroX. So MicroX is this open source project that Laurent has been working with for a very long time now and that has been just accepted this summer as a sandbox project on the CNCF Foundation. It is basically a set of tools and platforms to be able to do API mocking and testing. Originally coming from the Kubernetes space as a Kubernetes native tool, but now it has been extended into other different environments. And actually, test containers is one of the things we were going to be working around MicroX. So MicroX.io, it's the umbrella place to go where you can find some of these environments. And actually one of those, it's the MicroX test container Java. So this is one of the modules that I was mentioning before where we are able to work with specific vendors or providers like MicroX to get this library for Java, for example, in this case or other languages that allows you to embed the MicroX lifecycle and management of API contracts and tests as part of your unit test in a lightweight version that allows you to just throw away instances to be able to just start and stop and kill containers. So one of the things that we got from this updates it's that MicroX now has a very lightweight over jar version that allows you to manage most of the features available and used by the testing and mocking. So you are able to run those along your application. Now, this sounds really great, right? We are able to then use MicroX as containers with Java with any kind of framework. However, if you are already feeling some love and developer joy with Quarkus, we have something even better. And that's the MicroX Quarkus extension. So this is some of the great work that we are getting from MicroX and the Quarkus team. And this Quarkus extension allows you to get the benefits of the test containers plus MicroX plus Quarkus to be able to bring everything together all the simple joy development experience for Quarkus, all the benefits of API testing and mocking from MicroX, as well as the lifecycle management and management of tests from test containers. So this allows you to get MicroX working at the same time as your own application. It has a console, it's part of the console UI. So you have ever run the depth services in any other Quarkus extension. You have an option to get into that and being able to see that UI. So how it looks like? Well, it looks like something like this where we have the web UI that you know a lot from Quarkus and being able to find now a new block that it's the MicroX extension where you can then navigate into the MicroX UI where you can see the different APIs that are gonna be available and that you can start using for your application. And you can manage some of the capabilities from there, but most of the time what you want to do, it's really getting to your code, being able to use some of the features of the application as well as the support from MicroX. Now you will ask, well, how it looks like? And yeah, this is where we have some demo time. So we're gonna be able to show you something. Again, one of the things that we both love, it's pastry. So we're gonna build a pastry service that will be running on our machine. So let's imagine that we have a pastry service that gives us information about pastries. And we get some information of these pastries like the name of the pastry, the very French description of the pastry, the size of the pastry, some price and status if it is available or not. And we have a very more complex open API for this, right? And the idea is that we need to build a service that will give us information so we can then build an application that helps us to do online orders or that is gonna be used as the point of sale. And you can also, you know, share with partners so we can share with them how the great pastry we have from our pastries API bakers. And we are just gonna be on the sales side. So let's show you how this works in real life. So the first thing is that I have my application up and running. So what I did, it's, I just did, let's do some quick changes and make the definition day. And you have been following some of the content here. We have a very nice Quarkus application. So we are gonna create our orders application and see how this, it's creating, it's creating a Quarkus simple application. We also have a very nice open API that we are gonna be using for this. And yeah, let's go to our orders application and let's see some nice BS code extensions and we are loading this. Now the interesting thing here on the micro extension is that we can add the different extensions. So we're gonna be adding the microcs. So we are gonna Quarkus extension add microcs, Quarkus microcs to our project. So we are gonna be able to see that it's loading in the back. And then we are gonna be adding some extensions like rest easy. So we also have the add extensions to the Quarkus project on the BS code side. And we're gonna use the rest client. And we're gonna use Jackson, but let's do reactive Jackson. Yeah. Okay, so what you need to do is that if you go to Quarkus, there's a resources area where you can paste your open API that it's gonna be the base for your mocking and testing, right? So your owner is gonna be talking about more on the testing side. I'm gonna show you more on the mocking side. So where we're adding here is we have an application and open API specification that has some examples on the pastries that we have here. So this is one of the things that microcs uses for creating mocks. If you're specify some examples, it will use them to be able to provide them. There are more complicated ways to generate mocks using the AI assistant, but it's out of the scope of this demo. So the thing here is that microcs will detect anything that it's an open API or any other of the specifications that microcs uses for detecting mocks and tests. And we'll automatically read that from this service. So let's go with that. And let's run our Quarkus application. So Quarkus depth will bring us to the application. So we are loading this. And we see that test containers has been kicked in. So we are starting the services and we see that the container for the services for microc is already available at this URL. So if you want to go there, you can do that but an easy way to do that, it's just going to our localhost 8080. And we can go to the WI. And this is where I was mentioning that we have now microcs as a way to show you the UI of microcs. So if you log in here, you're able to go and get the most of the of microcs. And here you will see that the service that we added is now included as part of the API pastry service. And we have some of the mocks here that are available to be consumed. So if we need our code to be able to run, we can then see that we can replace the greeting resource that instead of saying just hello from rest easy reactive, we can then go into a full implementation. I'm just gonna switch to something that I have already working here. And that gives us the implementation of a pastry API client using the micro profile rest client, being able to retrieve pastries or pastries by name. Pastries just a simple record that we can use. And our greeting resource has been changed to inject our pastry client that is gonna be consuming and connecting to the mocking service provided on microcs. And what we're gonna be doing, it's just retrieve the pastries available from our API and then just collect the names of the pastries. So we can say, hello, this is our pastries. So let's try to run this and see if everything's working correctly. It's starting. We are running the Quarkus container and it is there. So if we go into our application, let's do HTTP, ADAD hello. And what will this be doing? It's just going into our services. Then just call the get pastries client that it's connecting to our service and then returning the information of our examples. If we want to do some changes, let's go to the pastry and then remove the croissant, for example. We are not gonna be using croissants, for example. And then let's just go to Quarkus Dev. And this time, again, starts a container very quickly, very easy downloading, registering all the mocks. And now we get back to the client and we can see that now the mock is just serving three different pastries, not croissant anymore. Sorry, we don't have that anymore and it is available. Other thing that I wanted to share to you is that it's not only for rest clients, but also we have different kind of services. So let's just update this and go to the API services. And yeah, pastries is one of the things we can see, but there's also GRPC. There's also information on mocks that you can do for a GraphQL, GRPC, SOAP services, WebSockets, a Sync API, all those kind of things that Microsoft can handle. Well, the test container can handle some of those with this lightweight version, but yeah, that's very interesting to work with. And this is the end of the first part. So, Lauren, can you take over and explain a little bit more on testing? Yeah, sure, sure. Thank you very much, we go for the demo. It's very clear how you can retrieve third-party dependencies and install everything on your laptop without having to wait for anybody to be available, any remote endpoints to be available, so you are totally free to work in isolation. So now we're gonna talk about the other side of the testing that is about not testing third-party dependencies, but testing the conformance of the code you're providing. And that's where we can use some techniques like, for example, contract tests. And contract testing is a technique for testing an integration point, so typically an API or a microservice interface, by checking each application in isolation, where you're ensuring that the messages it sends or receives conforms to a shared standing that is documented in a contract. So you see the importance of those contracts and they may have different forms, so it could be standard specifications like open API, like square the files, but it could be also descriptions like postman collections, code, documentation, and so on. And a side of the contracts, you see it in the demonstration from Hugo, we also think that examples have a great importance, because when they are carefully chosen, because we don't talk here about randomly generated example, we are talking about real-life examples, when they are carefully chosen, they can really translate the true expectations you have regarding this API. And so this is the best way for your consumers to really understand how to use your API and how to build some new stuff on top of this. And when they are carefully chosen, they can be turned into an exitable data set that can be used, obviously, to produce marks. That's what Hugo demonstrated a few minutes ago, but also to build a real test suite for your microservices and APIs. And this is exactly how Microsoft is working underneath. So the principle is very simple, but we hear a lot of people that are facing some real challenges when doing this at scale. And in fact, we identify the three challenges we are going through those challenges very quickly. The first one is the challenges about the origin of your contract. Should it be produced by the consumer, or should it be produced by the producer of the API? And we heard a lot about consumer-driven contract testing these last years. We think it's very powerful when it's used within the same team or within teams that have a great proximity. But we also think that it's not usually very applicable to large-scale organization or when you are designing an API that tends to be consumed by dozens, hundreds, thousands of consumers. So it always sounds like a chicken and egg problem to me because as a producer, you're not going to wait for the consumer to know what could be your capabilities and how to design and test your service, right? So it's quite, yes, a bit weird to me. Also, having made my organization are seeking autonomous teams for more velocity, more product orientation, and more responsibility. And so we started shifting from service design driven by obligation to service design method led by promises. And this shift for me is at the core of modern architecture, where robustness, where performance are paramounts, and where teams are empowered to fulfill this promise. And so in this era, you cannot place obligations on your team. So obviously this doesn't mean that we should be blind or deaf to the consumer's feedback. So, but I would say that being a producer-driven with a strong focus on consumer feedback is really a key for scaling. Another issue we are facing on the field is choosing the right type of contract artifacts. And basically we are all coders and using code seems very natural at the small scale, but you have to think about the time when you are scaling and you are dealing with much more languages, much more frameworks and could be very tricky to manage all these different styles of API. This really can become a nightmare. And secondly, there is also this problem of having to synchronize your code with some standard specification because even if you start writing code at the end of the day, you'll probably have to provide some kind of standard specification like open API or swipe a file to your consumers so that they can be able to really use your API. So if on top of that you are adding some consideration regarding versionings and so on, this can become really harder to maintain contract test based on codes. So we prefer an approach that is much more consistent and that is based on schema. And finally, the third and last challenge we see at scale is the one of having a contract test that may be scoped or driven by use case or much more global. And of course having requirements attached to a scope use case can be really great for documentation but only relying on this leads to two risks to me. You may have some capabilities in your API or microservice that are not covered by a contract test or you may also have inconsistent tests that may be spanned in your different use cases. So the Microsoft approach very briefly is default to an approach that allows you to scale and to use this technique of contract testing at large scale. So it is mainly produced driven with the ability to work at the schema level with all different types of specification standards. Hugo talked about it a few minutes ago so the open API could be GraphQL, VGRPC and so on. But these default approach can be customized and can be completed by integrating artifacts coming from consumers and by integrating some customization. And we'll see that in a few minutes in demo. So very briefly because we are running out of time in Microsoft we are able to do contract testing at two different levels. The first one is the foundation one. This is where we are checking the syntactic confirmance of your API. This means that it actually respects the structure of message. So consumers will be technically able to interact with this API. And the other one is the one of the behavior confirmance. Okay, when we are more focused on the business rules of your business domain. So this is what makes the API, the Microsoft service reliable regarding the business domain. So let me now switch to a demonstration. And in this demonstration I will focus on the contract testing part. So I will not follow on Hugo's demo on Java but I'll switch to a new language out here. I do contract testing stuff using a Node.js application. And basically let's imagine that I'm now focusing on this order service that is reusing my third party API, Pastry API. That's why demonstrated Hugo. But now I want to be sure that this order service also provide a robust API that is totally confirmant to my specification so that online services stores or even partners can build on top of my API. So that's it. Let me switch to the demonstration. So here I've got a TypeScript Node.js, nest.js application with that is exposing this API. It has an order controller here. It is implementing the business logic as well. And we have introduced here this microx test containers binding for Node.js or JavaScript language. So very easy to integrate this into your dependencies just had this single line in your package.json. And once you've done this, you have this ability to do exactly the same thing as Hugo previously. So you can then test your client libraries to be sure that you're able to reach out your third party library to handle protocol and network serialization stuff very, very easily. So basically I can here run a test here and this test will do exactly the same thing that has done for Hugo. So it will spin up a new microx container, configure everything and bind it to your application so that your application is actually these smoke services instead of the third party libraries. But now let's switch and let's focus on contract testing. So I have prepared here an empty test, a contract test. And I want to be sure that my API confirms to my open API spec. And this is where I'm gonna use microx. So not like in Quarkus where everything is hidden and done automatically for you. Here you will have to do a bit of plumbing, let's say, to be able to start the microx test container service. Okay. So this is one of the advantages of using Quarkus. Everything is already done automatically for you. But here in my setup method, I will start a new microx container, filling it with open service, order service open API and API pastries open API. In the tiered on method of this test, I will have to stop my container and to close my application because actually my application is running to expose my API so that I can test it. So this is what I'm doing just right here. Here I'm configuring my application and starting my application. Now in my test, I will have to use some specific object, specific utilities that is provided by microx. So you will simply have to ask for executing a new test. So you're building what we call the test request and actually you want to test the conformance of your code regarding this API or this service interface. You will use a testing strategy that is called open API schema validation and you will test this against your running application. So that's why you will use this kind of test container, specific alias to be able to target your running application within your test. And microx will execute this test, give you a result and you will be able to assert the success of the result and get eventually different details on the different test case and test steps that were executed. So let me just run this one here. Let's run the test and to hand and I'm gonna use this one here. And you will see that, oh, it fails. It fails, yes, it's not a success, it's just a failure. So hopefully we have the ability to have some details on what's going on. So we have this specific object here, the test result, and we can just let's say introspect and print out this subject to see what's going on. So I'm gonna execute the test once again. Okay. And here you can see that, yes, I've got a message here and it says that one of the response I get from this API when I try to create a new order, in fact, it has a missing required property. It is lacking the customer ID. Oh, yes, this is because I'm a bit a lazy developer and I forgot to re-copy the customer ID into the result. So let's just in command this one here. I made a mistake while implementing my business logic and that should be fixed executing the test once again and you see that it's now okay. It's green, it's fast. So you see it's a very, very convenient way of just checking that your services interface or APIs are really conformant to your specs. You don't have to write code or at least a very few, just asking Microsoft to do the test for you, okay. And Microsoft will reuse everything it found useful in your open API specs into your postman collection into maybe some other artifacts you fit it with to infer some kind of data sets, some test shoots and it will run everything for you, just giving you the outputs in case you have something that is not conformant with the specification. And so it could be really easy also to integrate different versions of your specs. So you can test with the latest one but you can also test with the previous one so that you are really sure within your development workflow that you are not introduced, breaking changes that you're still keeping the backward compatibility for example. So you don't have to wait for the CICD. You can use this directly into your laptop. So very convenient. One thing I wanted to demonstrate but we are too short here is that we have different kind of strategies. So you can reuse the definition found in an open API schema but you can also use these things called the postman strategy where for example, you can reuse different scripts and different assertions you have put into your postman collection if you're a true fan of postman collections for example. That's it for the demo. So let me now switch back to the conclusion to do the wrap up. So we've seen this kind of design. Hugo demonstrated that we are able with Microsoft to mock the part on the right, the third party libraries so that you don't have to wait for an environment to be ready. You can do this directly on your laptop and we have a take care about checking that the part on the left is really conformant to the specs and that you are really doing some things that will give you a high level of confidence regarding its capability to be integrated with other consumers, with other microservices that rely on this service. So as a key takeaways, we wanted today to, for you to be convinced that API and microservices contract testing is a technique you must master to be able to get this high level of confidence and to unlock the potential of decoupled architecture. When you're doing this at scale, there are challenges and we really do think that microcs that is a schema-based plus test container that can be directly integrated into your development workflow can be really a game changer to allow you to solve these scaling challenges. But even if we have a default approach based on schema, you also have the total flexibility to integrate your own testing strategy, your own additional artifacts so that you can really create your own strategy for testing and forgetting the best level of confidence within your microservices development. To finish on the microcs, I wanted to share with you this overview that we are doing this with all different kinds of API. Okay, so processes, REST, APIs, GraphQL, GRPC, and all things related to async API as well. Okay, with a lot of different supported protocols and yes, as I said previously, we are doing this with different language bindings so you can integrate this into your Java unit test, into your Node unit test, into your Golang unit test as well. So we are very polyglot, let's say. And finally, as we, yes, the very different shatter in microcs that we have this ability to cover the whole lifecycle and you may reuse the same tool and also most importantly, the same source of truth, the same specification, the same artifact on the whole lifecycle, starting with the inner loop on the developer laptop and getting back to the CI CD when microcs had been integrated for different plugins and getting back to confidence checking why not on your QA or even production environment within your Kubernetes cluster, for example. So thank you very much for attending this session. Thank you very much for your questions. And yes, just finishing on that, we need you because we are 100% open source projects so you can join us on Zulip, like the Quarkasting, we have a Zulip chat. You can follow us on Twitter and yes, if you try it, if you like it, feel free to connect with the community and distribute it to Shell and why not contribute to the project? Thank you very much. Thank you very much. Thank you, Lord. It was great to know more about testing and how you can do not only Java, but also other languages. If you wanna get started with your applications, being able to try and deploy and test in a Kubernetes environment, the Red Hat Developer Sandbox, it's been re-banned. So now you can try that, you can try Dev Spaces, you can try OpenShift AI. So that's something we really encourage you to try. And finally, well, thank you everyone. In the last slide, we are really happy to be here and we hope you enjoy the rest of your session. Valentina, if there's no other questions, then I think we are done for this moment. Yeah, thank you so much. I really, let me mute, okay. I really enjoyed the session. So I hope everyone enjoyed it as I did and everyone feel more confident about working with testing and containers and contracts APIs. So what we will do is that it seems we don't have any comments or questions, anything else that you may want to ask? If not, we will be finishing. We will give you a few minutes before we are starting the next session. The next session will be about cloud native application ML, the composing with cloud native and OpenShift. So I will see you in a few minutes. Thank you so much. Thank you so much, Dean. Such a great session. Thank you. Thank you everyone.