-
Couldn't load subscription status.
- Fork 68
⚠ (feat) Introduce new feature-gated metas endpoint #1643
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
Conversation
✅ Deploy Preview for olmv1 ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
1a96032 to
a27fada
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1643 +/- ##
==========================================
- Coverage 67.74% 67.48% -0.27%
==========================================
Files 57 59 +2
Lines 4620 4998 +378
==========================================
+ Hits 3130 3373 +243
- Misses 1265 1378 +113
- Partials 225 247 +22
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
17e0f9a to
729645c
Compare
|
What's the relation of this PR to #1642? Which PR is a duplicate and which should be reviewed? |
729645c to
478c152
Compare
@azych apologies for the confusion. You're just seeing the result of rapid experimentation. This is the one to review, but it's still a WIP. I've converted this PR to a draft. |
d8dcf61 to
f94eb2e
Compare
| httpError(w, fs.ErrNotExist) | ||
| return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should change to write a 200 status and write no content to the response body.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that index.Get() was only ever returning true (so this code path was never actually being hit). Something else solved the test case failure though, but I went ahead and cleaned up Get()'s signature 53692a9
| storeMetaFuncs = append(storeMetaFuncs, storeIndexData) | ||
| } | ||
|
|
||
| var ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throughout these lines where we setup and run concurrent channel writers and readers, we should add some comments to explain what is happening.
| return newMultiReadSeeker(srs...), true | ||
| } | ||
|
|
||
| func (i *index) getSectionSet(schema, packageName, name string) sets.Set[section] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing that occurs to me is that the indexed sections are always guaranteed to be sorted by the offset. We could likely take advantage of that fact and implement a more performant algorithm that can step directly through each slice rather than building a set for each slice, performing a set intersection, the converting back into a slice and resorting.
But this is something we can capture as a follow-up.
d76a738 to
870f38f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All follow ups are being tracked in other issues to try not to distract this effort any further.
| }) | ||
| } | ||
|
|
||
| func storageServerHandlerWrapped(l logr.Logger, cfg CatalogServerConfig) http.Handler { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit (follow-up): We could probably change CatalogServerConfig to have an http.Handler field instead of the entire LocalStorage field?
| defer s.m.RUnlock() | ||
|
|
||
| catalog := r.PathValue("catalog") | ||
| catalogFile, catalogStat, err := s.catalogData(catalog) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to defer catalogFile.Close() here.
Even better, now that we've got separate handling for all and query, maybe we go all the way to simply http.ServeFile?
068fd48
| case errors.Is(err, errInvalidParams): | ||
| code = http.StatusBadRequest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think I see any where that we call httpError with errInvalidParams. Seems we should add a check in the query handler for unexpected parameters?
| for i := 0; i < 10; i++ { | ||
| wg.Add(1) | ||
| go func() { | ||
| defer wg.Add(-1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| defer wg.Add(-1) | |
| defer wg.Done() |
| testCases := []struct { | ||
| name string | ||
| setupStore func() (*httptest.Server, error) | ||
| queryParams string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: might be nicer to use url.Values for more structure setup of the query params.
| { | ||
| name: "valid query with package schema", | ||
| queryParams: "?schema=olm.package", | ||
| expectedStatusCode: http.StatusOK, | ||
| expectedContent: `{"defaultChannel":"preview_test","name":"webhook_operator_test","schema":"olm.package"}`, | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any test that verifies that a query that matches multiple blobs returns all the blobs. We should add variations of that for each of schema, package, and name.
| if strings.Contains(tc.name, "If-Modified-Since") { | ||
| // Do an initial request to get a Last-Modified timestamp | ||
| // for the actual request | ||
| resp, err := http.DefaultClient.Do(req) | ||
| require.NoError(t, err) | ||
| resp.Body.Close() | ||
| req.Header.Set("If-Modified-Since", resp.Header.Get("Last-Modified")) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't base test logic on the content of a free-form test name. But maybe it makes sense to do this for every test case, where each test case is first sent without the header, and then resent with the header?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a fan of what I did here either, but for the lack of a better way of doing it I just went with string matching.
Now that I am thinking about it again with a clearer head, I think I can do better: have a "setup" func for each test, and only do a "pre-call" for this test in the setup function. I'll add this in the follow up.
|
|
||
| for _, tc := range testCases { | ||
| t.Run(tc.name, func(t *testing.T) { | ||
| req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/catalogs/test-catalog/api/v1/query%s", testServer.URL, tc.queryParams), nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should parameters the http method and test HEAD (which should work, but with no response body), as well as POST and DELETE, and PUT which should all fail with the unsupported method status code.
| queryParams: "?schema=olm.package", | ||
| expectedStatusCode: http.StatusNotModified, | ||
| expectedContent: "", | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add another test cases with an unknown parameter, expected to return BadRequest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And another when we get duplicate parameters? (i.e. 'query?package=foo&package=foo')
* refer: 1. [Metas Endpoint RFC] (https://docs.google.com/document/d/1s6_9IFEKGQLNh3ueH7SF4Yrx4PW9NSiNFqFIJx0pU-8/edit?usp=sharing) 2. [operator-framework/operator-controller-1643](operator-framework/operator-controller#1643) 3. [operator-framework/operator-controller-1713](operator-framework/operator-controller@45cdb37#diff-03c0636b035013a21712c5f4f04a30ae71ef533c9aa4a6d0724dc5575bf0dffdR9) * Required a vendor update to pull in [openshift/api-2202](https://github.com/openshift/api/pull/2202/files#diff-a8b6135d50534471326ea7bcd20e0f5eae25353f7788338060f718128a6a0b34R525) $ go get github.com/openshift/api@744790f2cff777b1bb29bdccce10e4e84cff0a69 $ go mod tidy $ go mod vendor Also needed $ go get openshift/client-go@f7ec47e to resolve vendoring inconsistency.
* refer: 1. [Metas Endpoint RFC] (https://docs.google.com/document/d/1s6_9IFEKGQLNh3ueH7SF4Yrx4PW9NSiNFqFIJx0pU-8/edit?usp=sharing) 2. [operator-framework/operator-controller-1643](operator-framework/operator-controller#1643) 3. [operator-framework/operator-controller-1713](operator-framework/operator-controller@45cdb37#diff-03c0636b035013a21712c5f4f04a30ae71ef533c9aa4a6d0724dc5575bf0dffdR9) * Required a vendor update to pull in [openshift/api-2202](https://github.com/openshift/api/pull/2202/files#diff-a8b6135d50534471326ea7bcd20e0f5eae25353f7788338060f718128a6a0b34R525) $ go get github.com/openshift/api@744790f2cff777b1bb29bdccce10e4e84cff0a69 $ go mod tidy $ go mod vendor Also needed $ go get openshift/client-go@f7ec47e to resolve vendoring inconsistency.
* refer: 1. [Metas Endpoint RFC] (https://docs.google.com/document/d/1s6_9IFEKGQLNh3ueH7SF4Yrx4PW9NSiNFqFIJx0pU-8/edit?usp=sharing) 2. [operator-framework/operator-controller-1643](operator-framework/operator-controller#1643) 3. [operator-framework/operator-controller-1713](operator-framework/operator-controller@45cdb37#diff-03c0636b035013a21712c5f4f04a30ae71ef533c9aa4a6d0724dc5575bf0dffdR9) * Required a vendor update to pull in [openshift/api-2202](https://github.com/openshift/api/pull/2202/files#diff-a8b6135d50534471326ea7bcd20e0f5eae25353f7788338060f718128a6a0b34R525) $ go get github.com/openshift/api@744790f2cff777b1bb29bdccce10e4e84cff0a69 $ go mod tidy $ go mod vendor Also needed $ go get openshift/client-go@f7ec47e to resolve vendoring inconsistency.
Description
Implementation of Metas Endpoint API RFC
--feature-gates=APIV1MetasHandler=trueto the binaryalldata.<base.url>/api/vi/metas?for each catalogNote: Some renaming from
query->metasdone in #1713Reviewer Checklist