 My name is Hyping and I'm so here besides the data scientists, we have fraud engineers. And Michael, Talix told me, don't tell other people we are fraud engineers. Yeah, because we are trying to catch those like frauders, suspicious customers and drivers. Yeah, so today I'm going to talk a little bit about having introduction on the key lab we are using and have some examples how to use the key lab CICD. Yeah, so I joined Golja no longer and when I joined Golja I was surprised to see how Golja is using key lab and because my previous experience was like use key hub and use big packet and I was wondering why here we are using key lab. Then I realized key lab has a very good feature of the CICD and it's already integrated and if you use key hub or big packet, usually you have to integrate with Jenkins or Circle I.O. or Drone I.O. A lot of other stuff to round up your tests, unit tests, integration tests or how to deploy to Kubernetes. The key job you have to set up on Jenkins is pretty hard and maintain Jenkins itself is a job but it could be because you have a huge team how to scale the Jenkins is another problem. So here we use key lab and a nice feature. Okay, key lab has some problem. I mean key lab.com has some problem. That's why I'm using our, hopefully I'm not fired. I'm using our office because I was trying to push my code to the key lab.com and I don't know what was the problem. Actually the first time I heard key lab was... When it went down. Yeah, when it went down. When it was in the news for the bad reason and they say it lost like six hours of data. In their post-modern they say they lost like 5,000 users, about 5,000 projects and 700 users around there. What happens when you're right? So I'm using the company one but when key lab.com is okay I will push, I will migrate the code to the key lab.com. So the nice thing of the key lab report is you have building pipelines. So usually within the pipeline you can have multiple stages. So pipeline is important. If you don't use key lab you have to build your own pipeline. So here I can show you, right now I have two stages. So once I check in my code to my branch the jobs, the pipeline will start to run. And you can define your own stage and here I have build and I have test. So test I have integration test, I have unit test and build basically just make sure it compiles. You can run, go build. Here later I will show you how to run the unit test and integration test. And you can add more. Let's say you can want to show the test coverage. So in GoJack one of the reports we use is we show the test coverage. If your merge request is drop the test coverage it just fill your jobs and you have to fix it. Otherwise we want to make sure we maintain certain test coverage. So you can also run, go lean turn. So make sure you are using the back practices. And you may also run the go report to show what was the percent. How well are you getting A or B or whatever. So I haven't done that. So this is the CI. I haven't integrated the CD yet. So basically you can easily build another stage and build your Docker image and deploy to push your Docker image to your Docker registry. And from there you can deploy to AWS or deploy to Google Cloud. So this is the introduction on the key lab. So I will give you very small examples. So right now everything is microservice. So the features of microservice is it calls another microservice and it talks to send DB. So this is the basic stuff. So microservice you talk to other service. You retrieve the data from your DB. So how we run the unit test and the integration test on the CI. So I'll give you some I give the example will show you how to run it. So so we can just give some thought thought. So definitely we don't run. So let's say this is my service one on the CI. Definitely I don't want this dependency right because you don't want your CI job is like intermittent. Sometimes fail is sometimes pass depends on some other service. So later the call I'll show you in a goal and how to remove this in dependency. This is one of the things I talk about and how to run integrate this DB. So integrate this DB is important because we can mock we can mock everything. We can even mock the DB but the mocking doesn't make sure your SQL is running correctly. So you know in the way you write the way you run SQL query on my SQL or Postgres or some other stuff is different. They also they all have their dialects. So I'll show you the code quickly. Okay. So this is a simple code. So this is the main. Okay. So I I borrowed this example from one of the blog I saw. It's on the blog go for academic something. Yeah. So they have a very simple API. So this API you call this temperature API give a city name Singapore. It will turn you the temperature. So this is calling external service. And I'm thinking how we integrate DB. So I'll give. So let's say you give the full name of Singapore will return you the temperature of the Singapore. If you give a short name. So I will retrieve the DB. So DB is very simple DB. You give us short name. It will turn you full name Singapore. Then we pass this couple to the external service. So by the way, I'm using the VS code. I don't know. I increase the phone. Okay. Yeah. So so first thing I talk about. So it's very basic stuff. I want to I want to cut this dependency because I'm a CI job. I don't want to hit external service. So here I define the this is my dependency. This environment have all the dependencies. So I define an interface called weather because it called external service weather. So because we use interface, it's easier to play to the dependency injection. So in the test, how we do it is we do a mock. And in the test, in the test, instead of calling the real service, I call the mock. And because this mock implement satisfy this interface. So in this main integration test, you will you will not call the external service. And you will use when you build, when you instantiate this mock, you pass the other parameters. Here you can do all the magic and return it back. It's just like, so if you have complicated cases, you can hear the logic will be more complicated. Because here it's just an example. It's just you turn whatever you will just return. Passing whatever thing will return. But also here the part you can use some library. You give a you give an interface. You give you you are generally a mocked struct. Then you can say on this return that on this return that but here is simple enough. We can all understand. Yeah, so this is this is the way we we decouple ourselves from the external service for the integration test. So how we run the integration test with the DB. We use the help from the gilab. So this is basically this is the way you build the pipeline. You just write one file, YAML file, gilab, dash, Seattle, YAML. So here you can see. Yeah, here we use the service. You can use the Postgres service. So here you will have a database running on the on the gilab. When when the gilab runner is running, it will create a DB for you. And you can do your integration from the endpoint hitting here and hitting your DB and coming back. Also, of course, here are the mock external service here. So you can see the integration test. How we write is we use the standard. We're hitting from the very endpoint. We mock. We use the HTTP test. This this is a very standard way to write if you want to hit the endpoint directly. So that's why it's considered integration test. And yeah, I think that's about it. And as I mentioned, if you want to have another stage, you have right now you have built, you have test, you want to deploy. You can easily, instead of using Golang, you can this image, you can use your Golang with Docker command. So in another stage, here we have stage build test, you can write a deploy. And in the deploy stage, you can run Docker build, Docker push to registry. Then from there you can deploy to whatever you want. Yeah, I think that's all. Can you run your own custom service for integration test? Custom service. What do you mean? You want a real thing? Yeah, you want to have some data in some DB which is not supported by GitLab. Cassandra, for example. Oh, you are saying this service, is it? Let's say, okay, I think I run up GitLab support service is like Redis, Postgres, MySQL. If you want Cassandra or Mango DB, you can build your own. Because it's simply just Docker file. You can run your Cassandra latest or whatever Mango latest. Yeah, it's quite nice. Instead of you, yeah. Yeah, you can do that. You mean this image? Yeah, you can do that. So this base image is how you run all your go build, go test is on this image. So it's actually a Docker image. Yeah, it's a Docker image. Yeah, you can run your own version. How do you run it? What does that mean? How do you reclaim that? So this is... It's a big database. Yeah, yeah. So I have this. This contains all my dependency. And I make this one to satisfy the HTTP, satisfy the HTTP.handler interface. Yeah, I don't know. Yeah, so you see this one? It have one function. So this will satisfy the handler interface, right? Because of this function. Yeah, so this is my main. This is my main. But in my main test... You have a mock weather? Yeah. You see where is it? Ah, this one. It created a mock. Yeah, see? Because this is the interface, I pass a mock. So the same thing will satisfy the handler interface. That's how we remove this dependency. But how you will load the integration test? Like, you are going to test the whole component, right? Yeah. How you are going to inject the mock? It is like, go has like build tags. It's like, are you loading particular different class for the testing? Okay. I'm not sure whether I get your question. But why I call it integration test is because I hit from the endpoint. Very endpoint. Handler test. Yeah. That's why I call it integration test. Then within this, you have many components. But integration test by my definition is not including the other services. Where is your code to load the database? To initialize the database? The shop Singapore? Yeah. So here, did I answer your question? Probably I... I wanted to know like how in the integration test, how you are going to inject the mocks for example. In the integration test, you can play the mocks, right? In the integration test? Yeah. This is how I inject the... Do you mean enter in here? This is how I inject the... Enter in test. Enter in test. How do you do system testing? Enter in. Yeah. So for example, you can have three microservices. Oh, okay. Only test one while mock two. Other two, right? Oh, you are saying you do want together all the services up together. Then you are testing this, hitting this, hitting that. This way, or you put a tag particular classes with big tags. For testing purpose, you will load only that mock classes. And it will be called. So it is non-linear as you are testing. So this one doesn't have all the... I mean, it only have the mock. If you want to test multiple up running, probably we can... We have another test cases running once it's deployed to production. It's more like another service like heating. Hitting and make sure it's written something. So tomorrow, if the contact of that service changes, you need fail? If the contract of the... So for example, tomorrow, in the JSON, it will be turning something. How many changed? Yeah. Then your... Oh, my test won't fail. But I know what you mean. Let's say this changed the contract, right? They air a one require a few. Because you are not... But probably my integration test doesn't concern this. Probably you have another end-to-end test to have all this make sure. I think there are some contract-driven tests. Yeah. I knew there are some contract-driven tests. You can run the CI, make sure the contract from another one is satisfied. Yeah, we can explore that. But there's also something like if you deploy to production, you can run your end-to-end test, make sure it's written. Yeah. It's mocked. It doesn't... If this contract change, it won't tell you. Yeah. How do you load the code and initialize the database? So... How do I initialize it? How do you initialize it? Is there some sort of like scaffold? Basically, I define this. Yes. It instantiates a postgres file. Yeah. Then here you define all the host, DB, and user and password. Yeah. And this is the way I use in my code. Okay. So in my code, you don't see this, but you see DB host, DB name, DB user, DB. Yeah. Yeah, password. So do you have any functions that actually seats your database? Do you have any function that seats your database? Oh, yeah. I use Goose. I don't know what... So I have this. So because it involves the DB, yeah, have Goose migration. Okay. Yeah. So it will populate your DB. Insert into the city. Yeah. Yeah. Yeah. Yeah. So I told you just short name and long name. Yeah. Yeah. Good. There are some other tools. I use Goose. Goose is quite nice. There are some that also send a migrate. There are two called migrate. Yeah. Got it. Yeah. I'm sorry. I forgot to show this. Where is this called? Where is this called? So this in the CI. In the script. Yeah. Ah. Got it. Got it. Yeah, but there's way to improve it because you can... This way means it's just a simple way. It's better way is you can run Goose in your integration test. You can... Every test you can up first. After every test you down. Yeah. So you make sure the DB is restored to the original state before every test is run. But this is a simple way. Just I want to make a point to use the DB. But definitely we can improve on this. Got it. Thanks. Yeah. Thanks a lot. Okay. Thank you.