Skip to content

Commit

Permalink
bug-1909637: allow searching for files from regular and try symbol up…
Browse files Browse the repository at this point in the history
…loads

Previously, you could sort of search for try uploads by searching for
"try/" in the key. But you couldn't search for regular uploads.

We recently changed the key data in the model, so "try/" no longer
appears in the key which breaks this flimsy filtering method.

This introduces a new upload_type filter field that lets you filter on
nothing (""), try upload files ("try"), and regular upload files
("regular").
  • Loading branch information
willkg committed Aug 19, 2024
1 parent 25dc578 commit 7138777
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 18 deletions.
37 changes: 29 additions & 8 deletions frontend/src/Files.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ class DisplayFiles extends React.PureComponent {
const filter = this.props.filter;
this.refs.key.value = filter.key || "";
this.refs.size.value = filter.size || "";
this.refs.upload_type.value = filter.upload_type || "";
this.refs.created_at.value = filter.created_at || "";
this.refs.bucketName.value = filter.bucket_name || "";
}
Expand All @@ -209,6 +210,7 @@ class DisplayFiles extends React.PureComponent {
event.preventDefault();
const key = this.refs.key.value.trim();
const size = this.refs.size.value.trim();
const upload_type = this.refs.upload_type.value.trim();
const created_at = this.refs.created_at.value.trim();
const bucketName = this.refs.bucketName.value.trim();
this.props.updateFilter({
Expand All @@ -217,13 +219,15 @@ class DisplayFiles extends React.PureComponent {
size,
created_at,
bucket_name: bucketName,
upload_type: upload_type,
});
};

resetFilter = (event) => {
this.refs.key.value = "";
this.refs.size.value = "";
this.refs.bucketName.value = "";
this.refs.upload_type.value = "";
this.refs.created_at.value = "";
this.submitForm(event);
};
Expand All @@ -238,6 +242,7 @@ class DisplayFiles extends React.PureComponent {
<th>Key</th>
<th>Size</th>
<th>Bucket</th>
<th>Upload type</th>
<th>Uploaded</th>
<th
className="bool-row is-clipped"
Expand All @@ -254,6 +259,7 @@ class DisplayFiles extends React.PureComponent {
<th>Time to complete</th>
</tr>
</thead>

<tfoot>
<tr>
<td>
Expand Down Expand Up @@ -282,6 +288,15 @@ class DisplayFiles extends React.PureComponent {
style={{ width: 140 }}
/>
</td>
<td>
<span className="select">
<select name="upload_type" ref="upload_type">
<option></option>
<option>regular</option>
<option>try</option>
</select>
</span>
</td>
<td>
<input
type="text"
Expand Down Expand Up @@ -316,6 +331,20 @@ class DisplayFiles extends React.PureComponent {
</td>
<td>{formatFileSize(file.size)}</td>
<td>{file.bucket_name}</td>
<td>
{file.upload && file.upload.upload_type === "try" ? (
<span className="tag is-info" title="try symbol upload">
try
</span>
) : (
<span
className="tag"
title="{file.upload.upload_type} symbol upload"
>
{file.upload.upload_type}
</span>
)}
</td>
<td>
{file.upload ? (
<Link
Expand All @@ -327,14 +356,6 @@ class DisplayFiles extends React.PureComponent {
) : (
<DisplayDate date={file.created_at} />
)}{" "}
{file.upload && file.upload.try_symbols ? (
<span
className="tag is-info"
title="Part of a Try build upload"
>
Try
</span>
) : null}
</td>
<td>{BooleanIcon(file.update)}</td>
<td>{BooleanIcon(file.compressed)}</td>
Expand Down
3 changes: 3 additions & 0 deletions tecken/api/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ class FileUploadsForm(UploadsForm):
size = forms.CharField(required=False)
created_at = forms.CharField(required=False)
completed_at = forms.CharField(required=False)
upload_type = forms.ChoiceField(
choices=[("", ""), ("try", "try"), ("regular", "regular")], required=False
)
key = forms.CharField(required=False)
update = forms.BooleanField(required=False)
compressed = forms.BooleanField(required=False)
Expand Down
12 changes: 12 additions & 0 deletions tecken/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,16 +387,19 @@ def _upload_files_build_qs(request):
form = forms.FileUploadsForm(request.GET)
if not form.is_valid():
return http.JsonResponse({"errors": form.errors}, status=400)

qs = FileUpload.objects.all()
for operator, value in form.cleaned_data["size"]:
orm_operator = "size__{}".format(ORM_OPERATORS[operator])
qs = qs.filter(**{orm_operator: value})

qs = filter_form_dates(qs, form, ("created_at", "completed_at"))
if form.cleaned_data.get("key"):
key_q = Q(key__icontains=form.cleaned_data["key"][0])
for other in form.cleaned_data["key"][1:]:
key_q &= Q(key__icontains=other)
qs = qs.filter(key_q)

include_bucket_names = []
for operator, bucket_name in form.cleaned_data["bucket_name"]:
if operator == "!":
Expand All @@ -405,6 +408,14 @@ def _upload_files_build_qs(request):
include_bucket_names.append(bucket_name)
if include_bucket_names:
qs = qs.filter(bucket_name__in=include_bucket_names)

if form.cleaned_data.get("upload_type", ""):
# NOTE(willkg): we have two upload types: try and regular. The try_symbols field
# is a boolean where try=True and regular=False, so we convert from a general
# upload types domain to the boolean domain of whether it's try upload or not.
# In the future, we may want to support other types by fixing the Upload model.
try_symbols = form.cleaned_data["upload_type"] == "try"
qs = qs.filter(upload__try_symbols=try_symbols)
return qs


Expand Down Expand Up @@ -455,6 +466,7 @@ def hydrate_upload(upload_id):
upload = uploads[upload_id]
uploads_cache[upload_id] = {
"id": upload.id,
"upload_type": "try" if upload.try_symbols else "regular",
"try_symbols": upload.try_symbols,
"user": {"id": upload.user.id, "email": upload.user.email},
"created_at": upload.created_at,
Expand Down
104 changes: 94 additions & 10 deletions tecken/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,62 @@ def test_upload_files(client, settings):
assert [x["id"] for x in data["files"]] == [file_upload2.id]


@pytest.mark.django_db
def test_upload_files_filter_upload_type(client, settings):
url = reverse("api:upload_files")

user = User.objects.create(username="user1", email="user1@example.com")
user.set_password("secret")
user.save()
assert client.login(username="user1", password="secret")

permission = Permission.objects.get(codename="view_all_uploads")
user.user_permissions.add(permission)

# Create upload data
regular_upload = Upload.objects.create(user=user, size=123_456)
regular_file = FileUpload.objects.create(
upload=regular_upload,
size=1234,
bucket_name="symbols-public",
key="bar.pdb/46A0ADB3F299A70B4C4C44205044422E1/bar.sym",
)

try_upload = Upload.objects.create(user=user, size=123_456, try_symbols=True)
try_file = FileUpload.objects.create(
upload=try_upload,
size=100,
bucket_name="symbols-public",
key="v1/libxul.so/A772CC9A3E852CF48965ED79FB65E3150/libxul.so.sym",
)

# Request all files--should return both files
response = client.get(url)
assert response.status_code == 200
data = response.json()
assert data["files"]
all_ids = {regular_file.id, try_file.id}
assert {x["id"] for x in data["files"]} == all_ids

# Request upload_type=""--should return both files
response = client.get(url, {"upload_type": ""})
assert response.status_code == 200
data = response.json()
assert {x["id"] for x in data["files"]} == all_ids

# Request upload_type="try"--should return only try file
response = client.get(url, {"upload_type": "try"})
assert response.status_code == 200
data = response.json()
assert {x["id"] for x in data["files"]} == {try_file.id}

# Request upload_type="regular"--should return only regular file
response = client.get(url, {"upload_type": "regular"})
assert response.status_code == 200
data = response.json()
assert {x["id"] for x in data["files"]} == {regular_file.id}


@pytest.mark.django_db
def test_upload_files_count(client):
url = reverse("api:upload_files")
Expand All @@ -863,14 +919,23 @@ def test_upload_files_count(client):
assert client.login(username="user1", password="secret")

# Create data
upload = Upload.objects.create(user=user, size=123_456)
file_upload_1 = FileUpload.objects.create(
upload=upload,
regular_upload = Upload.objects.create(user=user, size=123_456)
regular_file_upload = FileUpload.objects.create(
upload=regular_upload,
size=1234,
bucket_name="symbols-public",
key="v1/bar.pdb/46A0ADB3F299A70B4C4C44205044422E1/bar.sym",
key="bar.pdb/46A0ADB3F299A70B4C4C44205044422E1/bar.sym",
)

try_upload = Upload.objects.create(user=user, size=123_456, try_symbols=True)
try_file_upload = FileUpload.objects.create(
upload=try_upload,
size=50,
bucket_name="symbols-public",
key="libxul.so/9B6C6BD630483C5F453471EE0EEEB09A0/libxul.so.sym",
)
file_upload_2 = FileUpload.objects.create(

file_upload = FileUpload.objects.create(
size=100,
bucket_name="symbols-public",
key="libxul.so/A772CC9A3E852CF48965ED79FB65E3150/libxul.so.sym",
Expand All @@ -883,7 +948,7 @@ def test_upload_files_count(client):
data = response.json()
assert data["files"] == [
{
"id": file_upload_2.id,
"id": file_upload.id,
"key": "libxul.so/A772CC9A3E852CF48965ED79FB65E3150/libxul.so.sym",
"update": False,
"compressed": True,
Expand All @@ -894,7 +959,24 @@ def test_upload_files_count(client):
"upload": None,
},
{
"id": file_upload_1.id,
"bucket_name": "symbols-public",
"completed_at": None,
"compressed": False,
"created_at": ANY,
"id": try_file_upload.id,
"key": "libxul.so/9B6C6BD630483C5F453471EE0EEEB09A0/libxul.so.sym",
"size": 50,
"update": False,
"upload": {
"created_at": ANY,
"id": try_upload.id,
"try_symbols": True,
"upload_type": "try",
"user": {"id": user.id, "email": "user1@example.com"},
},
},
{
"id": regular_file_upload.id,
"key": "bar.pdb/46A0ADB3F299A70B4C4C44205044422E1/bar.sym",
"update": False,
"compressed": False,
Expand All @@ -903,8 +985,9 @@ def test_upload_files_count(client):
"completed_at": None,
"created_at": ANY,
"upload": {
"id": upload.id,
"id": regular_upload.id,
"try_symbols": False,
"upload_type": "regular",
"user": {"id": user.id, "email": "user1@example.com"},
"created_at": ANY,
},
Expand All @@ -925,14 +1008,15 @@ def test_upload_files_count(client):
"completed_at": None,
"compressed": False,
"created_at": ANY,
"id": file_upload_1.id,
"id": regular_file_upload.id,
"key": "bar.pdb/46A0ADB3F299A70B4C4C44205044422E1/bar.sym",
"size": 1234,
"update": False,
"upload": {
"created_at": ANY,
"id": upload.id,
"id": regular_upload.id,
"try_symbols": False,
"upload_type": "regular",
"user": {
"email": "user1@example.com",
"id": user.id,
Expand Down

0 comments on commit 7138777

Please sign in to comment.