@@ -386,6 +386,136 @@ def add_aliases(vuln, aliases):
386386 Alias .objects .create (alias = alias , vulnerability = vuln )
387387
388388
389+ class APIPerformanceTest (TestCase ):
390+ def setUp (self ):
391+ self .user = ApiUser .objects .create_api_user (username = "e@mail.com" )
392+ self .auth = f"Token { self .user .auth_token .key } "
393+ self .csrf_client = APIClient (enforce_csrf_checks = True )
394+ self .csrf_client .credentials (HTTP_AUTHORIZATION = self .auth )
395+
396+ # This setup creates the following data:
397+ # vulnerabilities: vul1, vul2, vul3
398+ # pkg:maven/com.fasterxml.jackson.core/jackson-databind
399+ # with these versions:
400+ # pkg_2_12_6: @ 2.12.6 affected by fixing vul3
401+ # pkg_2_12_6_1: @ 2.12.6.1 affected by vul2 fixing vul1
402+ # pkg_2_13_1: @ 2.13.1 affected by vul1 fixing vul3
403+ # pkg_2_13_2: @ 2.13.2 affected by vul2 fixing vul1
404+ # pkg_2_14_0_rc1: @ 2.14.0-rc1 affected by fixing
405+
406+ # searched-for pkg's vuln
407+ self .vul1 = create_vuln ("VCID-vul1-vul1-vul1" , ["CVE-2020-36518" , "GHSA-57j2-w4cx-62h2" ])
408+ self .vul2 = create_vuln ("VCID-vul2-vul2-vul2" )
409+ # This is the vuln fixed by the searched-for pkg -- and by a lesser version (created below),
410+ # which WILL be included in the API
411+ self .vul3 = create_vuln ("VCID-vul3-vul3-vul3" , ["CVE-2021-46877" , "GHSA-3x8x-79m2-3w2w" ])
412+
413+ from_purl = Package .objects .from_purl
414+ # lesser-version pkg that also fixes the vuln fixed by the searched-for pkg
415+ self .pkg_2_12_6 = from_purl ("pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.12.6" )
416+ # this is a lesser version omitted from the API that fixes searched-for pkg's vuln
417+ self .pkg_2_12_6_1 = from_purl (
418+ "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.12.6.1"
419+ )
420+ # searched-for pkg
421+ self .pkg_2_13_1 = from_purl ("pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.1" )
422+ # this is a greater version that fixes searched-for pkg's vuln
423+ self .pkg_2_13_2 = from_purl ("pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.2" )
424+ # This addresses both next and latest non-vulnerable pkg
425+ self .pkg_2_14_0_rc1 = from_purl (
426+ "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.14.0-rc1"
427+ )
428+
429+ set_as_fixing (package = self .pkg_2_12_6 , vulnerability = self .vul3 )
430+
431+ set_as_affected_by (package = self .pkg_2_12_6_1 , vulnerability = self .vul2 )
432+ set_as_fixing (package = self .pkg_2_12_6_1 , vulnerability = self .vul1 )
433+
434+ set_as_affected_by (package = self .pkg_2_13_1 , vulnerability = self .vul1 )
435+ set_as_fixing (package = self .pkg_2_13_1 , vulnerability = self .vul3 )
436+
437+ set_as_affected_by (package = self .pkg_2_13_2 , vulnerability = self .vul2 )
438+ set_as_fixing (package = self .pkg_2_13_2 , vulnerability = self .vul1 )
439+
440+ def test_api_packages_all_num_queries (self ):
441+ with self .assertNumQueries (4 ):
442+ # There are 4 queries:
443+ # 1. SAVEPOINT
444+ # 2. Authenticating user
445+ # 3. Get all vulnerable packages
446+ # 4. RELEASE SAVEPOINT
447+ response = self .csrf_client .get (f"/api/packages/all" , format = "json" ).data
448+
449+ assert len (response ) == 3
450+ assert response == [
451+ "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.12.6.1" ,
452+ "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.1" ,
453+ "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.2" ,
454+ ]
455+
456+ def test_api_packages_single_num_queries (self ):
457+ with self .assertNumQueries (10 ):
458+ self .csrf_client .get (
459+ f"/api/packages/{ self .pkg_2_14_0_rc1 .id } " , format = "json"
460+ )
461+
462+ def test_api_packages_single_with_purl_in_query_num_queries (self ):
463+ with self .assertNumQueries (11 ):
464+ self .csrf_client .get (
465+ f"/api/packages/?purl={ self .pkg_2_14_0_rc1 .purl } " , format = "json"
466+ )
467+
468+ def test_api_packages_single_with_purl_no_version_in_query_num_queries (self ):
469+ with self .assertNumQueries (98 ):
470+ self .csrf_client .get (
471+ f"/api/packages/?purl=pkg:maven/com.fasterxml.jackson.core/jackson-databind" , format = "json"
472+ )
473+
474+ def test_api_packages_bulk_search (self ):
475+ with self .assertNumQueries (71 ):
476+ packages = [
477+ self .pkg_2_12_6 ,
478+ self .pkg_2_12_6_1 ,
479+ self .pkg_2_13_1
480+ ]
481+ purls = [p .purl for p in packages ]
482+
483+ data = {'purls' : purls , 'purl_only' : False , 'plain_purl' : True }
484+
485+ resp = self .csrf_client .post (
486+ f"/api/packages/bulk_search" ,
487+ data = json .dumps (data ),
488+ content_type = "application/json" ,
489+ ).json ()
490+
491+ def test_api_packages_with_lookup (self ):
492+ with self .assertNumQueries (20 ):
493+ data = {'purl' : self .pkg_2_12_6 .purl }
494+
495+ resp = self .csrf_client .post (
496+ f"/api/packages/lookup" ,
497+ data = json .dumps (data ),
498+ content_type = "application/json" ,
499+ ).json ()
500+
501+ def test_api_packages_bulk_lookup (self ):
502+ with self .assertNumQueries (71 ):
503+ packages = [
504+ self .pkg_2_12_6 ,
505+ self .pkg_2_12_6_1 ,
506+ self .pkg_2_13_1
507+ ]
508+ purls = [p .purl for p in packages ]
509+
510+ data = {'purls' : purls }
511+
512+ resp = self .csrf_client .post (
513+ f"/api/packages/bulk_lookup" ,
514+ data = json .dumps (data ),
515+ content_type = "application/json" ,
516+ ).json ()
517+
518+
389519class APITestCasePackage (TestCase ):
390520 def setUp (self ):
391521 self .user = ApiUser .objects .create_api_user (username = "e@mail.com" )
0 commit comments