Serve locally stored fbc content via an http server#148
Serve locally stored fbc content via an http server#148joelanford merged 1 commit intooperator-framework:mainfrom
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #148 +/- ##
==========================================
- Coverage 79.10% 79.06% -0.04%
==========================================
Files 3 3
Lines 201 215 +14
==========================================
+ Hits 159 170 +11
- Misses 26 28 +2
- Partials 16 17 +1
☔ View full report in Codecov by Sentry. 📢 Have feedback on the report? Share it here. |
fe2259c to
be7f1dc
Compare
| } | ||
|
|
||
| func (s LocalDir) StorageServerHandler() http.Handler { | ||
| return http.StripPrefix(s.URL.Path, http.FileServer(http.FS(&filesOnlyFilesystem{os.DirFS(s.RootDir)}))) |
There was a problem hiding this comment.
Instead of calling os.DirFS() can we pass a fs.FS as a function parameter?
There was a problem hiding this comment.
I assume you're asking this for mocking purposes?
LocalDir needs to write files into the OS filesystem at RootDir and the whole point of moving this handler method into the LocalDir struct is to share that context to make it easier to keep things aligned.
At best, we would need some sort of writable FS interface for RootDir.
There was a problem hiding this comment.
Doable, but what value does it bring, if not for unit tests (made a comment about unit tests below)? If we can think of a valuable unit test this'll need to be done anyway.
There was a problem hiding this comment.
I assume you're asking this for mocking purposes?
Mocking the filesystem to test the handler implementation to be more precise, but yes.
LocalDir needs to write files into the OS filesystem at RootDir and the whole point of moving this handler method into the LocalDir struct is to share that context to make it easier to keep things aligned
I think this is fair, but I feel we could probably do better than a call to os.DirFS() to make it easier to test. That being said, I do think we could still create a temporary testing directory for unit testing purposes and inject it here so not a huge deal if we don't want to go into the effort of not using a direct os.DirFS() call.
At best, we would need some sort of writable FS interface for RootDir
I do wish the standard fs package had some way of having a writable FS interface, but if we wanted to completely abstract the use of the os package this would be needed.
If we can think of a valuable unit test this'll need to be done anyway.
Unit tests for the http server:
/catalogsreturns a 404/catalogs/<catalogName>returns a 404 (even if the directory exists)/catalogs/<catalogName>/all.jsonreturns 200 and expected JSON content
could also add unit tests specifically for the filesOnlyFilesystem but I think that would be covered in the above tests
There was a problem hiding this comment.
For fs interfaces, please use afero if the stock fs.FS doesn't meet your need.
| Expect(corev1.AddToScheme(scheme)).To(Succeed()) | ||
| Expect(rbacv1.AddToScheme(scheme)).To(Succeed()) | ||
| Expect(batchv1.AddToScheme(scheme)).To(Succeed()) |
There was a problem hiding this comment.
It seems like we should use the default scheme that includes these built-in types, rather than starting with an empty scheme and having to add built-in types one-by-one.
https://pkg.go.dev/k8s.io/client-go@v0.28.1/kubernetes/scheme#Scheme
There was a problem hiding this comment.
We do start with that, looks like it's the same in rukpak?
There was a problem hiding this comment.
You do need to add non-core types to the runtime.Scheme().
There was a problem hiding this comment.
Yes, I'm suggesting starting with scheme.Scheme instead of runtime.NewScheme(), because the former has all of the built-in types already added. Then all you have to worry about is adding the non-core types.
| buf := new(bytes.Buffer) | ||
| _, err = buf.ReadFrom(logReader) | ||
| Expect(err).ToNot(HaveOccurred()) | ||
| cfg, err := declcfg.LoadReader(buf) |
There was a problem hiding this comment.
Any reason not to just do a string comparison of the raw FBC json?
There was a problem hiding this comment.
If we stick with LoadReader, there's no need for the intermediate buffer. Just pass logReader directly into declcfg.LoadReader
There was a problem hiding this comment.
Reason to not to string comparison is how the information is laid out, ie lack of ordering guarantee.
There was a problem hiding this comment.
Go's JSON encoder has ordering guarantees for field names. The previous code in operator-registry would sort lists as well before sending them over the wire. Why wouldn't we want to add deterministic output to the set of expectations from the server?
There was a problem hiding this comment.
lack of ordering guarantee
Can you explain further? The all.json file is literally a file on disk and the written into the http response body. I don't see any possibility of non-determinism in the response.
| } | ||
| rawMessage, err := json.Marshal(value{PackageName: "prometheus", Version: "0.47.0"}) | ||
| Expect(err).To(Not(HaveOccurred())) | ||
| expectedDeclCfg := declcfg.DeclarativeConfig{ |
There was a problem hiding this comment.
Can we use a golden fixture on disk and have an UPDATE=true mode for tests to simply update the fixture?
There was a problem hiding this comment.
I have no idea what you mean exactly.
However while trying to decipher your statement I realized that I should probably not make a config by hand here, and instead read the file from the test folder. If that's what you meant by your comment then +1
There was a problem hiding this comment.
Yep - sorry for the nomenclature. "golden fixture" just means a file on disk in the repo that has the desired state. We check against it with a simple diff and have a helper that, instead of checking and failing on a diff, updates the file, to facilitate easier development in the future.
|
@joelanford @everettraven @stevekuznetsov Latest update switches to using a separate server than the metrics server. Currently in progress: refactoring server related code in Storage to make it more unit test-able + unit tests. And the two unresolved comments from above. Pushing what I have till now to see what we can do as follow up to make it more iterative, since current sprint commitment is at risk: Work blocked on this PR: (note again that I am working on the unit tests related refactoring + unit tests in the background) |
7a5ea29 to
7ead78b
Compare
70cb262 to
91ca8b1
Compare
everettraven
left a comment
There was a problem hiding this comment.
Approving pending green e2e
Closes operator-framework#113 Signed-off-by: Anik <anikbhattacharya93@gmail.com>
Closes #113