 Hi, I am Sergei and in this video we are going to fix a failing API test again This video is part of the debugging Galaxy tutorial So fixing an API test. Let me share my screen Here is the here is the tutorial and we are on API test failure So API tests, test various aspects of the Galaxy API. They also test general backend aspects of Galaxy that use the API They require a Galaxy instance. They are significantly slower than your unit tests But still they are fairly fast fast enough to give you a reasonably fast feedback when you are developing So heading on to the hands-on section Part one finding the failing test on github So again, like the unit test, we are going to follow the same process So why don't we head over to the Galaxy repository on github? So again, make sure you are in Galaxy project dug out Galaxy and make sure that you have the training branch selected again if you If you happen to be on the default branch, which is dev, you will need to click this button, get the drop-down menu and head all the way to the bottom Until you find the training branch. The training branch Contains the bugs which have been engineered and added to Galaxy especially to support this tutorial So After this we find the latest commit. It's this one zero two eb and so on And we click the red x Right next to the last commit In the red x we find api test slash test 3.7 and so on sometimes your screen resolution will only permit api test slash tests test 3 to be displayed. That's fine. This is the one. This is the failing workflow We need to look at again. I'm going to right click details Open link a new tab so that I can have this list of all the failures In a separate tab and this is the tab which has been opened Again, github very nicely auto scrolls all the way to the bottom So I don't have to scroll through 4 000 lines and I get this very scary list of failing tests. So let's head over to the tutorial to make sure we are Doing what we're supposed to be doing. So Click the same red x select the api tests try to find the failed tests Well, we see quite a few. There are eight failing tests Each of these lines starting with Failed is going to list the specific test that has failed in this workflow We don't need to look at all of them actually So if you click if you open the solution the solution will tell you the two tests Which uh, which you are going to Address in this tutorial in this in this part of the tutorial So first of all the long list the long list multiple failed tests Some of them were caused by bugs you'll be fixing in later sections of the tutorial Bugs are not independent tests are not independent. So one bug may cause more than one Failure that's why you see all those additional failures Sorry for that. You'll just have to ignore the rest for now. We look at these two failures one is test licenses dot pi Test 404 or unknown license and the other one is in the same test module test licenses dot pi And the test function is test get license. So this is the one we're going to Address and this is the one we're going to use to fix this bug part two Running the test locally again, we will run the individual tests locally You don't want to wait for feedback from running these tests remotely which will come Possibly in a few hours. This is not what you need You need quick feedback. So while it is Possible to run the test directly with pi test in this case We will use galaxy's test running script run test dot sh The script optimizes test runs by sharing the same instance of galaxy across multiple tests Without the script a new galaxy will be started for each test case class There are other reasons to run this script and for more information You can take a look at the documentation block at the top of that script and let me show you that script So heading over to my tutorial. This is my galaxy root And if you look at the files, you will see run tests dot sh so If we look at that file, you will see that the top of that file has a long section Which is detailed documentation about how to run This script and how this script is going to help you run specific tests Not not the entire test suite Although of course you can just use run test dot sh and it will run all the Tests which it can discover and that'll be a lot Back to the tutorial So Once again, we can use pi test and then specify the path to the test We will use run test dot sh script to get you into a habit of using that script for API tests Would that make a difference for this particular case? No But when you are running multiple tests, absolutely, yes, you don't want Galaxy to be recreated for every single test So without further ado, let's go ahead and run the failing tests, which is located in lib galaxy test API test licenses dot pi So pay attention the unit tests were located in test slash And so on and so forth the api tests are located in lib slash galaxy test and So run test dot sh Run Tests dash api lib galaxy test api And what was it test licenses and run Holding fingers crossed If you are running this for the first time on your machine, this may take a long time But subsequent runs will be fairly fast. So you see test session has started It has discovered three tests or rather it has collected three tests and it is running them Excellent two failed one passed and We have the same tests Failing that we were interested in so Let's head back to the tutorial and see what steps we need to Take two tests are failing. Do you see the error messages? Solution. Yes, we see the following error messages Let's check the Terminal Yes, here they are failed lib galaxy test api test licenses dot pi And that points to the specific test Function and the second one is the same thing just a different test function The error messages the error messages are assertion error request status code 500, which is a server error was not was not expected Value 404 body was invalid It doesn't really matter what exactly the error message says what matters is that we see a 500 error and a 404 error Back to the tutorial. So this means that instead of http status code 200 Well, we get an error status Again, sometimes multiple test failures may be caused by the same error and this is the case here So we're going to try to find this error fix it and hopefully fingers crossed This will fix both of these tests Heading to part three finding and fixing the issue So in this case, we can use either one of these tests to start debugging Let's let's use test get license As with the unit test first, let's take a look at the test function definition located in live galaxy test api test licenses dot pi It's in fact the same. Well, we know where it's located because that's the command We executed when we ran it. So instead of run test We are going to launch a text editor pointing to the module with the test function definition And it's a very small one, which is very nice It simplifies things. So test get license. I believe this is the one which failed. This is the second function test function definition Back to the tutorial As with this unit test first, let's take a look at the test function definition So test get license And here it is test get license Let's see what the tutorial says about this The important line is the third line So response equals self underscore get And it points to this string which uh, it passes at this string as an argument and the string is in fact An endpoint. So the test tells us exactly what api endpoint is called Therefore our next step is to examine the controller for this endpoint All the controller or rather for now almost all of the controllers for endpoints or for endpoints Are located in lib galaxy web apps galaxy api and we need the licenses module How do we know that? Well, because uh licenses is part of the endpoint and in most cases This would be a separate controller So back to the terminal We are going to Actually, let's open it side by side. So we don't have to check. What was the function Name so we had to lib galaxy Web apps galaxy Api and these are all the controllers. So there is an annotations controller authenticate controller and so on and so forth So we need the licenses controller. So licenses dot pi And here it is Back to the tutorial There are two controllers One is a legacy controller. One is an fb fast api controller. They have identical functionality. We can use either one We're going to use the fast api controller because well the legacy controller Will eventually go away. The fast api controller is here to stay So let's take a look at the fast api controller And in fact, I believe we don't need The file on the left anymore. Let's just double check Yes, so we can close it So here is our controller Once again, there are two identical controllers fast api licenses on line 29 this one and Licenses controller on line 48 this one We are going to work with the fast api licenses. So we have two methods here One is The top one which addresses the which serves the api licenses endpoint. The other one Serves the api slash licenses slash id or license id, which is a license specific license identifier Variable so the other one serves this endpoint and this is the one we care about Back to the tutorial So in the fbi in the fast api controller, you will see the get method that is responsible for fetching the data in response To a get HTTP request received at the licenses slash license identifier endpoint Let's see where that get method is so This is the router dot get is the function or the method decorator We don't care about it in this case Async def get this is the actual method which takes care of the endpoint We are debugging and it contains really just one line this return self dot licenses Licenses manager dot get license by id This is the line we care about to in order to debug this failure Back to the tutorial. So the only thing in this method that matters to us is the last line Why because despite All this syntax the method simply redirects the request to self licenses manager And if we read the code we'll quickly see that this variable holds an instance of licenses manager Which if we look at the import statement is located in lib galaxy managers licenses dot pi Which is where we should look next. So let's take a look at the code and make sure this sinks in So i'm on line 42 which is an excellent number for a line and Going to line 45 return self licenses manager get licenses by id So i'm calling the get licenses by id method of licenses manager. What is licenses manager? Let's take a look It is defined on line 30 licenses manager is Of type licenses manager. So what is licenses manager with the l and m capitalized? Let's take a look at that one It's defined. Well, it's imported at the very top from galaxy managers licenses import licenses manager So let's head on to license to galaxy managers licenses again. Let's open this side by side I'm heading to lib Galaxy oops Sorry enter key problems Once again, let's try again lib Galaxy Managers Licenses Here it is And this is where the licenses manager is defined and if I look for it. It's right here on line 101 Now in licenses manager. I need a method Get licenses by id This one and it's defined right here At the very bottom of licenses manager. So I'm going to close the left side of the screen. So it gets out of the way And I am left with licenses manager. So get license by id once again. What what is this? This is the method which is invoked From the controller from the api controller Which services the api endpoint? Which causes Which indicates an api test failure So something bad is happening this method Back to the Carefully trace the code in licenses manager will find the error. Do you see it? Let's take a look at the code So get license by id takes identifier, which is a string as an argument and let's see We call The get method of the licenses manager And that get method will get us something And that something is assigned to variable named license Next line 130 if license dot get license id is none and none is the default value Then we raise exception an exception. We raise the object not found exception, which causes the 405 error So this happens so line 131 happens line 132 does not happen because then we would get the Expected result and the test would not fail. We would get a HTTP code status code 200 So the exception is raised which means Which means that the if clause The expression on line 130 if license get so and so it's none evaluates to true So this line is at fault So it cannot find The license we are looking for let's take a look at line 129 This line calls The get method of the license manager, which is defined On line 116 right above almost above this method. So here it is Let's head back to the tutorial to make sure we are on the right track solution The get license by id method raises an object not found error Which results in the 404 status we see in the test result This error is direct is a direct result of the get method called on the previous line Take a look at that method. So we are looking at this get method So get takes a uri as an argument if uri not in self by index return cell by index, etc, etc, etc so Code can be difficult to read Galaxy code can be impossible to read. So instead of trying to figure out this we can simply rewrite this Of course after looking at checking what exactly is underscore by index, but you will Very easily see that by index is in fact A dictionary and you can find that out by looking at where by index is defined Actually underscore by index, which is on line 111. So here it's an instance variable on the license manager Object so here we go underscore by index So The value of by index local variable is assigned to it and what is by index without the underscore? Well, it's defined on line 104 and it's just a Back to our get method reading And rephrases That will become clear So the clause if uri not in self by index return cell by index can be rephrased as if key not in dictionary return The value stored by that key in that dictionary And that makes no sense whatsoever Essentially, you are saying if the key is not in dictionary then get the value for that key From that dictionary It should be the opposite if key is in dictionary then get the item of that key. So the not after key This one is clearly a typo or obviously more accurately a very very wicked edit made for the purpose of setting up this Wonderful learning experience. So let's remove this negation and we run the test back to the terminal If you are right not in self index If you are right in self by index write and quit And we run the test Hopefully it will pass Success we win We fixed it back to the tutorial So we run the test everything worked Congratulations. So again now commit your edit. Don't forget to supply a useful commit message and move on to the client errors So again, let's see get status One file is changed get add all get commit And here you would add a useful message Let's see Get commit and the message would be remove negation fix api Test this is probably not the most useful message Not the most useful commit message for this case, but it's well good enough And now you would commit and now you would push your branch So once again Congratulations, the api test is fixed and now you can move on to fixing the client test. Thank you