Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1577 use users measurements #539

Merged
merged 13 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from datetime import datetime, timedelta

from django.db.models import Q
from shared.upload.utils import query_monthly_coverage_measurements

from codecov.commands.base import BaseInteractor
from codecov.db import sync_to_async
from codecov_auth.models import Owner
from plan.service import PlanService
from services.redis_configuration import get_redis_connection
from utils.uploads_used import get_uploads_used

redis = get_redis_connection()

Expand All @@ -18,4 +18,4 @@ def execute(self, owner: Owner):
plan_service = PlanService(current_org=owner)
monthly_limit = plan_service.monthly_uploads_limit
if monthly_limit is not None:
return get_uploads_used(redis, plan_service, monthly_limit, owner)
return query_monthly_coverage_measurements(plan_service=plan_service)
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from datetime import datetime, timedelta

from django.test import TransactionTestCase
from shared.django_apps.reports.models import ReportType
from shared.upload.utils import UploaderType, insert_coverage_measurement

from codecov_auth.tests.factories import OwnerFactory
from core.tests.factories import CommitFactory, RepositoryFactory
Expand All @@ -16,11 +18,23 @@ def setUp(self):
self.user_with_uploads = OwnerFactory()
repo = RepositoryFactory.create(author=self.user_with_uploads, private=True)
commit = CommitFactory.create(repository=repo)
report = CommitReportFactory.create(commit=commit)
report = CommitReportFactory.create(
commit=commit, report_type=ReportType.COVERAGE.value
)

# Reports all created today/within the last 30 days
for i in range(2):
UploadFactory.create(report=report)
# Explicit add insert_coverage_measurement as we'll do this every time that we make an upload
upload = UploadFactory.create(report=report)
insert_coverage_measurement(
owner_id=self.user_with_uploads.ownerid,
repo_id=repo.repoid,
commit_id=commit.id,
upload_id=upload.id,
uploader_used=UploaderType.CLI.value,
private_repo=repo.private,
report_type=report.report_type,
)

report_within_40_days = UploadFactory.create(report=report)
report_within_40_days.created_at += timedelta(days=-40)
Expand All @@ -34,17 +48,50 @@ def setUp(self):
)
trial_repo = RepositoryFactory.create(author=self.trial_owner, private=True)
trial_commit = CommitFactory.create(repository=trial_repo)
trial_report = CommitReportFactory.create(commit=trial_commit)
trial_report = CommitReportFactory.create(
commit=trial_commit, report_type=ReportType.COVERAGE.value
)

report_before_trial = UploadFactory.create(report=trial_report)
report_before_trial.created_at += timedelta(days=-12)
report_before_trial.save()
upload_before_trial = insert_coverage_measurement(
owner_id=self.trial_owner.ownerid,
repo_id=repo.repoid,
commit_id=commit.id,
upload_id=report_before_trial.id,
uploader_used=UploaderType.CLI.value,
private_repo=repo.private,
report_type=report.report_type,
)
upload_before_trial.created_at += timedelta(days=-12)
upload_before_trial.save()

report_during_trial = UploadFactory.create(report=trial_report)
report_during_trial.created_at += timedelta(days=-5)
report_during_trial.save()
upload_during_trial = insert_coverage_measurement(
owner_id=self.trial_owner.ownerid,
repo_id=repo.repoid,
commit_id=commit.id,
upload_id=report_during_trial.id,
uploader_used=UploaderType.CLI.value,
private_repo=repo.private,
report_type=report.report_type,
)
upload_during_trial.created_at += timedelta(days=-5)
upload_during_trial.save()

report_after_trial = UploadFactory.create(report=trial_report)
insert_coverage_measurement(
owner_id=self.trial_owner.ownerid,
repo_id=repo.repoid,
commit_id=commit.id,
upload_id=report_after_trial.id,
uploader_used=UploaderType.CLI.value,
private_repo=repo.private,
report_type=report.report_type,
)

async def test_with_no_uploads(self):
owner = self.user_with_no_uploads
Expand Down
22 changes: 16 additions & 6 deletions graphql_api/tests/test_owner.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
from datetime import timedelta
from unittest.mock import patch

import pytest
from django.test import TransactionTestCase, override_settings
from django.utils import timezone
from freezegun import freeze_time
from graphql import GraphQLError
from shared.django_apps.reports.models import ReportType
from shared.upload.utils import UploaderType, insert_coverage_measurement

from codecov.commands.exceptions import MissingService, UnauthorizedGuestAccess
from codecov_auth.models import OwnerProfile
Expand Down Expand Up @@ -250,9 +251,7 @@ def test_repository_dispatch_to_command(self, command_mock):
data = self.gql_request(query, owner=self.owner)
assert data["owner"]["repository"]["name"] == repo.name

@patch("redis.Redis.get")
def test_resolve_number_of_uploads_per_user(self, mocked_get):
mocked_get.return_value = None
def test_resolve_number_of_uploads_per_user(self):
query_uploads_number = """{
owner(username: "%s") {
numberOfUploads
Expand All @@ -263,9 +262,20 @@ def test_resolve_number_of_uploads_per_user(self, mocked_get):
author__plan=PlanName.BASIC_PLAN_NAME.value, author=self.owner
)
first_commit = CommitFactory.create(repository=repository)
first_report = CommitReportFactory.create(commit=first_commit)
first_report = CommitReportFactory.create(
commit=first_commit, report_type=ReportType.COVERAGE.value
)
for i in range(150):
UploadFactory.create(report=first_report)
upload = UploadFactory.create(report=first_report)
insert_coverage_measurement(
owner_id=self.owner.ownerid,
repo_id=repository.repoid,
commit_id=first_commit.id,
upload_id=upload.id,
uploader_used=UploaderType.CLI.value,
private_repo=repository.private,
report_type=first_report.report_type,
)
query = query_uploads_number % (repository.author.username)
data = self.gql_request(query, owner=self.owner)
assert data["owner"]["numberOfUploads"] == 150
Expand Down
2 changes: 1 addition & 1 deletion requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ factory-boy
fakeredis
freezegun
https://github.com/codecov/opentelem-python/archive/refs/tags/v0.0.4a1.tar.gz#egg=codecovopentelem
https://github.com/codecov/shared/archive/1dc95a2ac3c07ca211319e65a90ea35592c825c1.tar.gz#egg=shared
https://github.com/codecov/shared/archive/9ca2efbb2c109ecfe241143ecd1c6f38c3820a0b.tar.gz#egg=shared
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't merge until updated to latest after this is merged, codecov/shared#214

google-cloud-pubsub
gunicorn>=22.0.0
https://github.com/photocrowd/django-cursor-pagination/archive/f560902696b0c8509e4d95c10ba0d62700181d84.tar.gz
Expand Down
7 changes: 5 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ freezegun==1.1.0
# via -r requirements.in
google-api-core[grpc]==2.11.1
# via
# google-api-core
# google-cloud-core
# google-cloud-pubsub
# google-cloud-storage
Expand Down Expand Up @@ -391,7 +392,9 @@ requests==2.31.0
# shared
# stripe
rfc3986[idna2008]==1.4.0
# via httpx
# via
# httpx
# rfc3986
rsa==4.7.2
# via google-auth
s3transfer==0.5.0
Expand All @@ -402,7 +405,7 @@ sentry-sdk==1.40.4
# shared
setproctitle==1.1.10
# via -r requirements.in
shared @ https://github.com/codecov/shared/archive/1dc95a2ac3c07ca211319e65a90ea35592c825c1.tar.gz
shared @ https://github.com/codecov/shared/archive/9ca2efbb2c109ecfe241143ecd1c6f38c3820a0b.tar.gz
# via -r requirements.in
simplejson==3.17.2
# via -r requirements.in
Expand Down
8 changes: 5 additions & 3 deletions upload/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from shared.github import InvalidInstallationError
from shared.reports.enums import UploadType
from shared.torngit.exceptions import TorngitClientError, TorngitObjectNotFoundError
from shared.upload.utils import query_monthly_coverage_measurements

from codecov_auth.models import (
GITHUB_APP_INSTALLATION_DEFAULT_NAME,
Expand All @@ -36,7 +37,6 @@
from utils.config import get_config
from utils.encryption import encryptor
from utils.github import get_github_integration_token
from utils.uploads_used import get_uploads_used, increment_uploads_used

from .constants import ci, global_upload_token_providers

Expand Down Expand Up @@ -566,7 +566,10 @@ def check_commit_upload_constraints(commit: Commit):
report__commit=commit
).exists()
if not did_commit_uploads_start_already:
if get_uploads_used(redis, plan_service, limit, owner) >= limit:
if (
query_monthly_coverage_measurements(plan_service=plan_service)
>= limit
):
log.warning(
"User exceeded its limits for usage",
extra=dict(ownerid=owner.ownerid, repoid=commit.repository_id),
Expand Down Expand Up @@ -769,7 +772,6 @@ def dispatch_upload_task(
3600,
timezone.now().timestamp(),
)
increment_uploads_used(redis, repository.author)
commitid = task_arguments.get("commit")

TaskService().upload(
Expand Down
47 changes: 39 additions & 8 deletions upload/tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
from django.conf import settings
from django.test import TransactionTestCase
from rest_framework.exceptions import Throttled, ValidationError
from shared.config import get_config
from shared.django_apps.reports.models import ReportType
from shared.upload.utils import UploaderType, insert_coverage_measurement

from codecov_auth.models import GithubAppInstallation, Service
from core.tests.factories import CommitFactory, OwnerFactory, RepositoryFactory
Expand Down Expand Up @@ -163,8 +164,6 @@ def test_check_commit_constraints_settings_disabled(db, settings):
def test_check_commit_constraints_settings_enabled(db, settings, mocker):
settings.UPLOAD_THROTTLING_ENABLED = True
author = OwnerFactory.create(plan=PlanName.BASIC_PLAN_NAME.value)
something = None
mocker.patch("redis.Redis.get", return_value=something)
repository = RepositoryFactory.create(author=author, private=True)
public_repository = RepositoryFactory.create(author=author, private=False)
first_commit = CommitFactory.create(repository=repository)
Expand All @@ -173,16 +172,48 @@ def test_check_commit_constraints_settings_enabled(db, settings, mocker):
fourth_commit = CommitFactory.create(repository=repository)
public_repository_commit = CommitFactory.create(repository=public_repository)
unrelated_commit = CommitFactory.create()
first_report = CommitReportFactory.create(commit=first_commit)
fourth_report = CommitReportFactory.create(commit=fourth_commit)
first_report = CommitReportFactory.create(
commit=first_commit, report_type=ReportType.COVERAGE.value
)
fourth_report = CommitReportFactory.create(
commit=fourth_commit, report_type=ReportType.COVERAGE.value
)
check_commit_upload_constraints(second_commit)
for i in range(300):
UploadFactory.create(report__commit__repository=public_repository)
# ensuring public repos counts don't count torwards the quota
first_upload = UploadFactory(report=first_report)
insert_coverage_measurement(
owner_id=author.ownerid,
repo_id=public_repository.repoid,
commit_id=public_repository_commit.id,
upload_id=first_upload.id,
uploader_used=UploaderType.CLI.value,
private_repo=public_repository.private,
report_type=first_report.report_type,
)
# ensuring public repos counts don't count towards the quota
check_commit_upload_constraints(second_commit)
for i in range(150):
UploadFactory.create(report=first_report)
UploadFactory.create(report=fourth_report)
another_first_upload = UploadFactory.create(report=first_report)
insert_coverage_measurement(
owner_id=author.ownerid,
repo_id=repository.repoid,
commit_id=first_commit.id,
upload_id=another_first_upload.id,
uploader_used=UploaderType.CLI.value,
private_repo=repository.private,
report_type=first_report.report_type,
)
fourth_upload = UploadFactory.create(report=fourth_report)
insert_coverage_measurement(
owner_id=author.ownerid,
repo_id=repository.repoid,
commit_id=fourth_commit.id,
upload_id=fourth_upload.id,
uploader_used=UploaderType.CLI.value,
private_repo=repository.private,
report_type=fourth_report.report_type,
)
# first and fourth commit already has uploads made, we won't block uploads to them
check_commit_upload_constraints(first_commit)
check_commit_upload_constraints(fourth_commit)
Expand Down
Loading
Loading