-
Notifications
You must be signed in to change notification settings - Fork 370
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
Add block adapters unit tests #5317
Conversation
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.
pkg/block/azure/adapter.go
Outdated
@@ -325,7 +325,7 @@ func (a *Adapter) Walk(ctx context.Context, walkOpt block.WalkOpts, walkFn block | |||
return err | |||
} | |||
} | |||
if marker = resp.NextMarker; marker == nil { | |||
if marker = resp.NextMarker; marker == nil || *marker == "" { |
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.
Are both nil and empty string really an option? Yikes.
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.
Yes - unfortunately verified with real adapter
pkg/block/params/block.go
Outdated
@@ -46,4 +46,5 @@ type Azure struct { | |||
StorageAccessKey string | |||
TryTimeout time.Duration | |||
PreSignedExpiry time.Duration | |||
Url *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.
What is this?
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 is a config parameter for testing purposes to provide a custom URL to override the default URL template - added comment
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.
Maybe change to Endpoint
?
var params []func(*mem.Adapter) | ||
adapterTest.TestAdapter(t, block.BlockstoreTypeMem, params) | ||
} | ||
// TODO (niro): Need to enable |
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.
A marker so you won't forget
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.
pkg/block/azure/main_test.go
Outdated
|
||
func runAzurite(dockerPool *dockertest.Pool) (string, func()) { | ||
ctx := context.Background() | ||
resource, err := dockerPool.Run("mcr.microsoft.com/azure-storage/azurite", "latest", []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.
Pin a version or wake up one day to find out we're not compatible with latest
no more :)
pkg/block/azure/main_test.go
Outdated
if err != nil { | ||
panic(err) | ||
} | ||
hosts.AddHost("127.0.0.1", accountHost) |
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.
Are we overriding the host machine /etc/hosts
file? If so, I'm worried about this one. is there any other way that doesn't require overriding the machine /etc/hosts
? Test can crash half way through leaving garbage in that file..
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.
By default the emulator uses an IP style URL where the account name is part of the pah. This breaks our code due to how we parse the URL as we expect to account to be the domain.
So we need to add a host to our local IP which maintains the same structure as the production service URL.
This was the best option I found to do that - I'm open to better suggestions
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.
Gotcha, so the real problem is that we don't support accounts as part of the path.
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.
@nopcoder suggested that we'll leverage s3.local.lakefs.io
somehow. Is it possible to use a real DNS record that will point to localhost?
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.
The domain is comprised from the account name - which is dynamically determined. How do you suggest to deal with that?
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 add a DNS record *.local.azurite.lakefs.io
(or something similar) that points to 127.0.0.1
. Then for every account name xx
we will use the host name xx.local.azurite.lakefs.io
, thus avoiding hosts file modifications.
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.
The usual way is to spin up everything (test and Azurite) inside a single docker-compose environment.
On the one hand, users cannot edit hosts lookup -- this should never work.
In the past we had a DNS record for ease of deployment of local S3 gateways with host-based addressing. It makes a log of sense for quick-starting users. But using a DNS record here hurts in other ways, it means "unit" tests require Internet connectivity.
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.
As an alternative, you can override net.DefaultResolver
with something that resolves *.azurite.example.net
but falls back on the original DefaultResolver for everything else.
pkg/block/azure/main_test.go
Outdated
client, err := service.NewClientWithSharedKeyCredential(url, cred, nil) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
// Check connectivity with containerName | ||
_, err = client.GetAccountInfo(ctx, nil) | ||
if err != nil { | ||
panic(err) | ||
} |
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 think the below lines cover connectivity check
pkg/block/blocktest/adapter.go
Outdated
obj := block.ObjectPointer{ | ||
StorageNamespace: storageNamespace, | ||
Identifier: contents, | ||
IdentifierType: block.IdentifierTypeRelative, |
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.
Checking Full identifiers is critical too.
{"simple", "abc", []string{"one ", "two ", "three"}}, | ||
{"nested", "foo/bar", []string{"one ", "two ", "three"}}, |
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 will fail for some adapters. For example, S3 forces all parts except the last to be at least 5MB.
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.
Understand - lets handle this when it becomes an issue?
return tree | ||
} | ||
|
||
func testAdapterMultipartUpload(t *testing.T, adapter block.Adapter, storageNamespace 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.
Aborting multipart uploads is also important.
It can be added in a different PR.
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.
Yes - not everything was covered in this PR, I'll open a separate issue
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.
Credit goes to @nopcoder 😄 |
…it-tests # Conflicts: # pkg/block/params/block.go # pkg/config/config.go
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.
Requesting changes to consider alternatives to hosts file modifications.
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.
Minor comment about encapsulating tests from The Internet as far as possible.
pkg/block/azure/main_test.go
Outdated
if err != nil { | ||
panic(err) | ||
} | ||
hosts.AddHost("127.0.0.1", accountHost) |
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.
The usual way is to spin up everything (test and Azurite) inside a single docker-compose environment.
On the one hand, users cannot edit hosts lookup -- this should never work.
In the past we had a DNS record for ease of deployment of local S3 gateways with host-based addressing. It makes a log of sense for quick-starting users. But using a DNS record here hurts in other ways, it means "unit" tests require Internet connectivity.
pkg/block/azure/main_test.go
Outdated
if err != nil { | ||
panic(err) | ||
} | ||
hosts.AddHost("127.0.0.1", accountHost) |
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.
As an alternative, you can override net.DefaultResolver
with something that resolves *.azurite.example.net
but falls back on the original DefaultResolver for everything else.
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.
Thanks for applying the hosts change!
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.
Nice! But I worry about binding port 53 in particular, and any constant port in general. Tests should bind only ephemeral ports, or they risk unpleasant surprises (PC firewall popups, outright refusal on POSIX, inability to run the test twice concurrently, etc.).
Can we
pkg/block/azure/main_test.go
Outdated
} | ||
|
||
srv := &dns.Server{ | ||
Addr: ":53", |
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 think binds to a specific port on the host machine. But that port may be occupied, maybe someone runs dnsmasq! Also because this uses a port <1024 it has to run as root on some systems.
Consider binding only on "127.0.0.1:0" or similar, and then querying the server which ephemeral port it received. Not sure you can do it with this DNS server package though. I think that this dns.Server might be able to bind an ephemeral port if you configure it with Addr: "127.0.0.1:0"
, and then fetch that port using net.SplitHostPort(server.Listener.Addr().String())
.
# Conflicts: # pkg/block/azure/adapter.go # pkg/block/local/adapter.go # pkg/block/local/adapter_test.go # pkg/block/mem/adapter_test.go
Had to do a big refactor due to removal of the Walk function in master. |
d69cad8
to
d9bf3d6
Compare
d9bf3d6
to
6043605
Compare
6043605
to
a16fb04
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.
Thanks!
One thing missing from the tests that is particularly relevant to the local block adapter in production is testing that path traversal doesn't work.
- Paths like
a/b/./c
must not be the same asa/b/c
(maybe they should error out). - Paths like
a/b/../b/c
must not be the same asa/b/c
(maybe they should error out). - Paths like
a///b
must be handled correctly or error out (POSIX will treat them asa/b
). - Paths like
namespace/prefix/../../../../../../../etc/passwd
that escape out ofnamespace/prefix
must error out. - Paths like
namespace/prefix/a/b/\0/c
where \0 is the NUL char (byte 0) must either error out or be interpreted the same on POSIX filesystems in local mode and on lakeFS.
Another thing to test (which might be considerably more difficult!) is that POSIX filesystems use the same sort as
pkg/block/azure/client_cache.go
Outdated
// For testing purposes - override default url template | ||
if params.URL != 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.
If this really is only for testing, consider renaming the configuration option to something like url_for_testing
. Comments are too easy to ignore.
pkg/block/blocktest/adapter.go
Outdated
"github.com/treeverse/lakefs/pkg/ingest/store" | ||
) | ||
|
||
func TestAdapter(t *testing.T, adapter block.Adapter, storageNamespace, externalPath 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.
This function probably should not be named Test*
, that's the name of a test function. Maybe something like VerifyAdapter
?
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.
Maybe I'm missing something - but this is a test function
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 really: it's a helper function for writing test functions as described in package testing.
Final counterpoint from me on this topic: suppose TestAdapter included reading the config and therefore its callers would set all values from the environment. It would need to have signature TestAdapter(t *testing.T)
-- and then package testing would try to run it! In that case you would need to rename the func. So naming a function Test*
is confusing when you expect it not to run automagically.
@@ -81,7 +83,7 @@ func (l *LocalWalker) Walk(_ context.Context, storageURI *url.URL, options WalkO | |||
} | |||
const dirPerm = 0o755 | |||
_ = os.MkdirAll(l.cacheLocation, dirPerm) | |||
cacheName := filepath.Join(l.cacheLocation, nanoid.Must()+"-import.json") | |||
cacheName := filepath.Join(l.cacheLocation, gonanoid.Must()+"-import.json") |
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 understand. Shouldn't this live under the system temp file area, and be handled that way?
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.
local block adapter is constrained to the provided path and repo namespace (and configured allowed external prefixes).
We cannot assume the user allows access to the temp path.
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.
Import assume local adapter is configured to a shared location - so cache folder must be under the adapter's path.
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 might be quite surprising or confusing to users. We should take care to document this.
@@ -81,7 +83,7 @@ func (l *LocalWalker) Walk(_ context.Context, storageURI *url.URL, options WalkO | |||
} | |||
const dirPerm = 0o755 | |||
_ = os.MkdirAll(l.cacheLocation, dirPerm) | |||
cacheName := filepath.Join(l.cacheLocation, nanoid.Must()+"-import.json") | |||
cacheName := filepath.Join(l.cacheLocation, gonanoid.Must()+"-import.json") | |||
const cachePerm = 0o644 | |||
if err := os.WriteFile(cacheName, jsonData, cachePerm); err != 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.
What deletes this file? Especially consider what happens during failure: if the file is not deleted, the user will try again... and nothing will release this file. Especially especially consider what happens during unexpected failure.
The usual way to handle temporary files in POSIX is:
- Create a temporary file (
creat
). - Delete it.
- Write whatever contents you need.
lseek
back to the start of the file.- Read whatever you need.
- ...
close
the file.
POSIX filesystems explicitly support this mode: A deleted file has no name, and is deleted when no open file descriptors remain on it. This pattern is already implemented in lakeFS.
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.
In case a continuation token (file) is required for the next read, we cannot deleted the file.
The write and read will happen in a different context, and therefore we cannot use the pattern you described.
I added a remove in case of an error.
I agree we do need to have a cleanup mechanism for stale continuation token files, but not quite sure how we should do it - in any case I don't think this should be under the scope of this PR.
I'll open a new issue for it.
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.
Understood that this is not part of this PR. Note also that keeping temporary files in the permanent storage area (previous comment) makes this even more confusing.
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.
Looks great @N-o-Z - added my comments/concerns
pkg/block/namespace.go
Outdated
Prefix: key.Key, | ||
}, nil | ||
} | ||
|
||
func ResolveNamespace(defaultNamespace, key string, identifierType IdentifierType) (QualifiedKey, error) { |
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.
block.ResolveNamespace - think we should name it a bit different than the name we have on the interface or name the method on the interface differently.
It can be that block.ResolveNamespace -> DefaultResolveNamespace
Or .ResolveNamespace -> ResovleQualifiedKey
I'm trying to make it clear to the caller what the code will return for each case.
pkg/block/namespace.go
Outdated
// QK - QualifiedKey interface | ||
type QK interface { | ||
Format() string | ||
GetStorageType() StorageType | ||
GetStorageNamespace() string | ||
GetKey() 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.
- Think this one should be named QualifiedKey as the block adapter interface will work only with the interface.
- We can name the block level implementation as Common/GeneralQualifiedKey and the local one as LocalQualifiedKey. Need to identify the difference between the block level qualified key type and functions vs the interface which provided by our interface - the application level would like to work with the block adapter level type which is QualifiedKey interface.
- Naming GetXXX -> XXX - I understand that as long as the implementation provides the same property it can conflict - but maybe we can find different names for struct/interface so we can keep using getters without a Get prefix.
// QK - QualifiedKey interface | |
type QK interface { | |
Format() string | |
GetStorageType() StorageType | |
GetStorageNamespace() string | |
GetKey() string | |
type QualifiedKey interface { | |
Format() string | |
StorageType() StorageType | |
StorageNamespace() string | |
Key() string |
pkg/block/namespace.go
Outdated
var ( | ||
ErrInvalidNamespace = errors.New("invalid namespace") | ||
ErrInvalidStorageType = errors.New("invalid storage type") | ||
) |
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.
- Move to errors.go
- Check maybe we can merge as both are used while we parse / build addresses - as "invalid address" with format that will render "namespace" and "storage type"
pkg/api/controller.go
Outdated
@@ -302,7 +300,7 @@ func (c *Controller) GetPhysicalAddress(w http.ResponseWriter, r *http.Request, | |||
} | |||
|
|||
address := c.PathProvider.NewPath() | |||
qk, err := block.ResolveNamespace(repo.StorageNamespace, address, block.IdentifierTypeRelative) | |||
qk, err := c.Catalog.ResolveNamespace(repo.StorageNamespace, address, block.IdentifierTypeRelative) |
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 prefer not to have another ResolveNamespace on catalog too as already have another two.
if f.params != nil { | ||
localParams, err = f.params.BlockstoreLocalParams() | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
return local.NewLocalWalker(localParams), 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.
- The comment is related to the
f.params
- do we still require it as an interface? - Is it an option to call the builder without proving the right configuration for the adapter? maybe we should just return an error in f.params is nil.
if s3EndpointURL != "" { | ||
config = aws.Config{ | ||
Endpoint: aws.String(s3EndpointURL), | ||
Region: aws.String("us-east-1"), // Needs region for validation as it is AWS client | ||
S3ForcePathStyle: aws.Bool(true), | ||
} |
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.
Why in this case we provide defaults? I prefer the caller to be explicit or let the adapter pull from the env.
pkg/block/factory/build.go
Outdated
@@ -128,7 +129,11 @@ func buildS3Adapter(statsCollector stats.Collector, params params.S3) (*s3a.Adap | |||
func BuildGSClient(ctx context.Context, params params.GS) (*storage.Client, error) { | |||
var opts []option.ClientOption | |||
if params.CredentialsFile != "" { | |||
opts = append(opts, option.WithCredentialsFile(params.CredentialsFile)) | |||
credPath, err := homedir.Expand(params.CredentialsFile) |
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.
The config package usually expand the ~ to the user home dir.
return tree | ||
} | ||
|
||
func testAdapterMultipartUpload(t *testing.T, adapter block.Adapter, storageNamespace 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.
Wonder how is this test associate to the real world case as multipart upload have minimum size of 5MB (unless it is the last part)
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.
AFAIK this only applies to S3.
I assume that when we enable the unit tests for S3 we will need to modify the test
Co-authored-by: Ariel Shaqed (Scolnicov) <ariels@treeverse.io>
…o task/add-adapter-unit-tests
Co-authored-by: Ariel Shaqed (Scolnicov) <ariels@treeverse.io>
Co-authored-by: Barak Amar <barak.amar@treeverse.io>
Thanks @arielshaqed These are very important test cases and as I dived more into it I understand that this requires addressing in a separate PR. |
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.
Thanks looks good. The only thing that hurts the "go" eyes is the multiple return values by extractParamsFromObj
- looks we just need good struct name use per adapter to hold the values.
@@ -228,6 +233,7 @@ func testAdapterMultipartUpload(t *testing.T, adapter block.Adapter, storageName | |||
} | |||
|
|||
func testAdapterExists(t *testing.T, adapter block.Adapter, storageNamespace string) { | |||
// TODO (niro): Test abs paths |
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.
Still relevant - alt open an issue
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.
@@ -81,7 +83,7 @@ func (l *LocalWalker) Walk(_ context.Context, storageURI *url.URL, options WalkO | |||
} | |||
const dirPerm = 0o755 | |||
_ = os.MkdirAll(l.cacheLocation, dirPerm) | |||
cacheName := filepath.Join(l.cacheLocation, nanoid.Must()+"-import.json") | |||
cacheName := filepath.Join(l.cacheLocation, gonanoid.Must()+"-import.json") |
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.
Import assume local adapter is configured to a shared location - so cache folder must be under the adapter's path.
…it-tests # Conflicts: # pkg/api/controller.go
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.
Thanks, a lot of thought and effort are very evident!
Huge improvement, and probably needed since before I joined the company. Please make sure to link an issue for path traversal tests once we have one in a comment on this PR, so we don't lose track.
pkg/block/blocktest/adapter.go
Outdated
"github.com/treeverse/lakefs/pkg/ingest/store" | ||
) | ||
|
||
func TestAdapter(t *testing.T, adapter block.Adapter, storageNamespace, externalPath 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.
Not really: it's a helper function for writing test functions as described in package testing.
Final counterpoint from me on this topic: suppose TestAdapter included reading the config and therefore its callers would set all values from the environment. It would need to have signature TestAdapter(t *testing.T)
-- and then package testing would try to run it! In that case you would need to rename the func. So naming a function Test*
is confusing when you expect it not to run automagically.
@@ -81,7 +83,7 @@ func (l *LocalWalker) Walk(_ context.Context, storageURI *url.URL, options WalkO | |||
} | |||
const dirPerm = 0o755 | |||
_ = os.MkdirAll(l.cacheLocation, dirPerm) | |||
cacheName := filepath.Join(l.cacheLocation, nanoid.Must()+"-import.json") | |||
cacheName := filepath.Join(l.cacheLocation, gonanoid.Must()+"-import.json") |
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 might be quite surprising or confusing to users. We should take care to document this.
@@ -81,7 +83,7 @@ func (l *LocalWalker) Walk(_ context.Context, storageURI *url.URL, options WalkO | |||
} | |||
const dirPerm = 0o755 | |||
_ = os.MkdirAll(l.cacheLocation, dirPerm) | |||
cacheName := filepath.Join(l.cacheLocation, nanoid.Must()+"-import.json") | |||
cacheName := filepath.Join(l.cacheLocation, gonanoid.Must()+"-import.json") | |||
const cachePerm = 0o644 | |||
if err := os.WriteFile(cacheName, jsonData, cachePerm); err != 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.
Understood that this is not part of this PR. Note also that keeping temporary files in the permanent storage area (previous comment) makes this even more confusing.
* Add block adapters unit tests * CR Fix 1 * Fix linter issue * Add fullpath tests * Ignore static check * CR Fixes * CR Fixes 2 * Rebase fixes * Fix lint error * Fix S3 Adapter namespace * Fix GS Adapter namespace * Fix ugc test * More fixes * Update pkg/block/blocktest/adapter.go Co-authored-by: Ariel Shaqed (Scolnicov) <ariels@treeverse.io> * Update pkg/block/blocktest/adapter.go Co-authored-by: Ariel Shaqed (Scolnicov) <ariels@treeverse.io> * Update pkg/block/mem/adapter.go Co-authored-by: Barak Amar <barak.amar@treeverse.io> * More fixes * Revert WriteRange * Add comment * More fixes * More fixes 2 --------- Co-authored-by: Ariel Shaqed (Scolnicov) <ariels@treeverse.io> Co-authored-by: Barak Amar <barak.amar@treeverse.io>
Linked Issue
Closes #5246
Change Description
Background
Adding generic unit test for block adapters, in order to align functionality and behavior
For the scope of this PR, added testing for the majority of the adapter interface, and enabled unit testing for local and Azure block adapters
Breaking Change?
No