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

add unit test for ValidateLayout function #4

Merged
merged 1 commit into from
Oct 6, 2016
Merged

add unit test for ValidateLayout function #4

merged 1 commit into from
Oct 6, 2016

Conversation

xiekeyang
Copy link
Contributor

@@ -122,3 +103,45 @@ func TestUnpackLayer(t *testing.T) {
t.Fatal(err)
}
}

func createTarFile(name string, list []tarContent) (descriptor, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We use tar files for image-layout as well. This helper is about creating layers, so it should probably be createLayer or similar to distinguish from image-layout tooling.

Copy link
Contributor

Choose a reason for hiding this comment

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

And we have a public Descriptor type in github.com/opencontainers/image-spec/specs-go. Can we return that instead of the private, local descriptor (one step closer to being able to drop the local descriptor ;)?

Copy link
Member

Choose a reason for hiding this comment

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

And we have a public Descriptor type in github.com/opencontainers/image-spec/specs-go. Can we return that instead of the private, local descriptor (one step closer to being able to drop the local descriptor ;)?

if it doesn't need to call any of the method attached to descriptor - then yes I would use the public Descriptor as well - otherwise let's keep descriptor for now

if _, err = io.Copy(tw, bytes.NewReader(content.b)); err != nil {
tw.Close()
gw.Close()
f.Close()
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like a job for defer ;).

Copy link
Contributor

@wking wking Sep 16, 2016

Choose a reason for hiding this comment

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

Perhaps you avoid it because you want to ensure the file is completed and closed before you start hashing it. You could jump through some hoops to get the defered functions to fire, but it's probably easier and more efficient to use something like:

var file *os.File
file, err = os.Create(name)  // + err checking
defer file.Close()
hash := sha256.New()
counter := NewCountingWriter()  // TODO: write this up.  It counts bytes written to it and discards the content
hashingWriter := io.MultiWriter(file, hash, counter)
gzipWriter := gzip.NewWriter(hashingWriter)
defer gzipWriter.Close()
// create tarWriter and writer content
err = tarWriter.Close() // + err checking
err = gzipWriter.Close() // + err checking
return &specs.Descriptor{
  MediaType: v1.MediaTypeImageLayer,
  Digest: fmt.Sprintf("sha256:%x", h.Sum(nil)),
  Size: counter.Size,
}, nil

On success, the deferred closes might error out (because we've already successfully closed the files). But who cares? We successfully closed the files. On error, we're ignoring possible Close errors. But who cares? We're already returning an error.

err = os.MkdirAll(filepath.Join(root, "refs"), 0700)
if err != nil {
t.Fatal(err)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This image-layout directory initialization also duplicates existing logic in manifest_test.go. Can we pull it out into createDirectoryImageLayout or some such?

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, it looks like manifest_test.go is only stubbing in the blobs directory, but not setting up the rest of image-layout. It would certainly help if we had a createDirectoryImageLayout with the more complete logic you have here so we could have a full image-layout there instead of its current partial format.

return descriptor{}, err
}

err = os.Rename(layerPath, filepath.Join(root, "blobs", "sha256", desc.Digest))
Copy link
Contributor

Choose a reason for hiding this comment

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

manifest_test.go is also doing similar post-creation renaming. Can we use createLayerFile there as well?

t.Fatal(err)
}

err = ValidateLayout(root, []string{"latest"}, nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

It's a bit odd to have latest explicitly here, but to have it implicit in the createRefFile call earlier. Can we have createRefFile(root string, ref string, descriptor *specs.Descriptor) err?

@wking
Copy link
Contributor

wking commented Sep 16, 2016

On Fri, Sep 16, 2016 at 01:01:27AM -0700, Antonio Murdaca wrote:

+func createTarFile(name string, list []tarContent) (descriptor, error) {

And we have a public Descriptor type in
github.com/opencontainers/image-spec/specs-go. Can we return that
instead of the private, local descriptor (one step closer to being
able to drop the local descriptor ;)?

if it doesn't need to call any of the method attached to
descriptor - then yes I would use the public Descriptor as well

  • otherwise let's keep descriptor for now

I think having public and private descriptor types is more
complication than the convenience of methods is worth. I've converted
the methods to functions in #5 (among other things ;) if you want to
see how it looks.

@xiekeyang
Copy link
Contributor Author

I improve the patch according to reviewer's comments.

  • set up common functions for creating tar file, image layers and hashed digest blobs.
  • apply the functions for manifest unit test.
  • set up unit test for ValidateImageLayout.
  • set up configurable reference.
  • make these changes in unit test files, not to join binary compiling. If other implementation need them, it is easy to move the functions to functionality files.

PTAL.

cc @wking @runcom @stevvooe @jonboulle

// generate sha256 hash
h := sha256.New()
file, err := os.Open(tarfile)
err = os.MkdirAll(filepath.Join(root, "blobs", "sha256"), 0700)
Copy link
Contributor

Choose a reason for hiding this comment

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

You should use createImageLayoutBundle here to get oci-layout, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems some inappropriate to use createImageLayoutBundle here.
the TestUnpackLayer prerequisite is just layer file with right path and its descriptor. It even needn't real manifest file. So it is enough to make layer dir and create layer file.
If TestUnpackLayer function is missing some test case( I read testManifest.unpack() function, and think TestUnpackLayer is fine), it is another story.
if it is correct?


// generate sha256 hash
hash := sha256.New()
size, err := io.Copy(hash, file)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a second pass through a file that you just streamed to disk. It would be more efficient to hash and size while you were streaming to disk, but as long as this is just for the test suite a second pass is probably fine.

}

func createRefFile(root string, mft descriptor) error {
refpath := filepath.Join(root, "refs", "latest")
Copy link
Contributor

Choose a reason for hiding this comment

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

"latest"refTag.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

@wking
Copy link
Contributor

wking commented Sep 18, 2016

On Sat, Sep 17, 2016 at 11:16:24PM -0700, xiekeyang wrote:

xiekeyang commented on this pull request.

  • gw := gzip.NewWriter(f)

- tw := tar.NewWriter(gw)

  • tw.WriteHeader(&tar.Header{Name: "test", Size: 4, Mode: 0600})
  • io.Copy(tw, bytes.NewReader([]byte("test")))
  • tw.Close()
  • gw.Close()

- f.Close()

  • // generate sha256 hash
  • h := sha256.New()
  • file, err := os.Open(tarfile)
  • err = os.MkdirAll(filepath.Join(root, "blobs", "sha256"), 0700)

It seems some inappropriate to use createImageLayoutBundle here.
the TestUnpackLayer prerequisite is just layer file with right
path and its descriptor. It even needn't real manifest file. So it
is enough to make layer dir and create layer file.

…/blobs/sha256/… is part of an image-layout, but not a complete
image layout (e.g. it has no oci-layout file). If the unpacker
implementation checked for an oci-layout file to confirm “yes, this is
an image-layout 1.0.0. I can lookup the blob at {algo}/{hash}”, then
it would fail this test as it stands. I think any unpacker which
expects to be using an image-layout should be checking for that
oci-layout file, and consider it a bug that the unpacker apparently
doesn't check. If we use createImageLayoutBundle, then this test will
continue to pass after we fix that bug.

@xiekeyang
Copy link
Contributor Author

@wking

…/blobs/sha256/… is part of an image-layout, but not a complete
image layout (e.g. it has no oci-layout file). If the unpacker
implementation checked for an oci-layout file to confirm “yes, this is
an image-layout 1.0.0. I can lookup the blob at {algo}/{hash}”, then
it would fail this test as it stands. I think any unpacker which
expects to be using an image-layout should be checking for that
oci-layout file, and consider it a bug that the unpacker apparently
doesn't check. If we use createImageLayoutBundle, then this test will
continue to pass after we fix that bug.

I'm all for you. But I honestly dislike to fix other bugs on this patch.
My preference is to commit only image_test.go for image layout validation file on this patch.
And fix manifest unpacking problem and improve the manifest unit test on other patch.
WDYT?

@wking
Copy link
Contributor

wking commented Sep 18, 2016

On Sun, Sep 18, 2016 at 01:09:05AM -0700, xiekeyang wrote:

But I honestly dislike to fix other bugs on this patch. My
preference is to commit only image_test.go for image layout
validation file on this patch. And fix manifest unpacking problem
and improve the manifest unit test on other patch.

It's all going to end up in the same stomach ;). My preference would
be to have multiple commits in this PR, but if you want to punt some
of it to a follow-up PR I'm ok with that. The (small) risk of
splitting this sort of thing is that the original contributor looses
interest after the PR that partially transitions to the new system,
and other folks have to pick up the pieces (and either revert or
complete the transition) on their behalf.

@xiekeyang
Copy link
Contributor Author

xiekeyang commented Sep 18, 2016

@wking
I research func (m *manifest) unpack related functions, find it is just responsible for unpack layers. Before it is called, finding manifest, finding config and manifest validation are always done. So manifest.unpack() needn't to check whole image bundle.
The mechanism may be confused, and need reconstruct, which seems not a bug. I suggest that we had better not to expend this PR scope. And I'd try to improve the mechanism on new PR.
WDYT?

@xiekeyang
Copy link
Contributor Author

@xiekeyang xiekeyang changed the title migrate #image-spec/pull/310 add unit test for ValidateLayout function Sep 19, 2016
@wking
Copy link
Contributor

wking commented Sep 19, 2016

On Sun, Sep 18, 2016 at 02:28:09AM -0700, xiekeyang wrote:

Before it is called, finding manifest, finding config and manifest
validation are always done. So manifest.unpack() needn't to check
whole image bundle.

It still needs to pull layers from the image-layout directory, so I
think we want a full image-layout structure. But we're having trouble
convincing each other, so that seems like a good enough reason to
punt. As it stands in 966be8f, I think this PR is generally moving
us in a good direction. If there's too much in the air to be able to
get to the bottom of our differences here, I'm ok picking up those
discussions in follow-up work. And if/when #5 lands I think all of
these image/*_test.go will be using the generic engines, so we won't
have to worry about whether a partially-setup image-layout makes sense
or not.

@xiekeyang
Copy link
Contributor Author

cc @stevvooe @runcom @jonboulle

Signed-off-by: xiekeyang <keyang.xie@gmail.com>
@xiekeyang
Copy link
Contributor Author

As we need to confirm and fix some problem in func (m *manifest) unpack, I'd like to narrow this PR, only for function ValidateLayout, which I think it is OK. And I'm working on the above discussed issue and will present new PR.

cc @wking @stevvooe

@wking
Copy link
Contributor

wking commented Sep 22, 2016

On Thu, Sep 22, 2016 at 01:19:54AM -0700, xiekeyang wrote:

As we need to confirm and fix some problem in func (m *manifest) unpack, I'd like to narrow this PR, only for function
ValidateLayout, which I think it is OK.

f3064f0e85687e just dropped all of your changes from
image/manifest_test.go. I think those were solid, useful changes, so
I don't see a need to drop them here. But if the image/image_test.go
stuff lands faster because you've dropped them, I'm ok with the
additional punt.

@xiekeyang
Copy link
Contributor Author

@wking Right. hopefully this image test will stand. And I'll submit manifest test.
cc @s-urbaniak @jonboulle @runcom PTAL.

@xiekeyang
Copy link
Contributor Author

PTAL.

@vbatts
Copy link
Member

vbatts commented Sep 27, 2016

LGTM

@vbatts vbatts merged commit ef40309 into opencontainers:master Oct 6, 2016
@xiekeyang xiekeyang deleted the unit-test branch October 7, 2016 03:07
wking added a commit to wking/image-tools that referenced this pull request Jan 20, 2017
Outsource this stuff to avoid duplication of effort.

I have no idea why newDescriptor was returning just the hex and
createHashedBlob (its only consumer) was fixing that (by the
"Normalize the hashed digest" comment).  But that is how the image
tests have worked since they landed in e85687e (unit test for layout
validation, 2016-09-22, opencontainers#4).  This commit drops the "Normalization"
hack and fixes newDescriptor to actually return a valid digest.

Signed-off-by: W. Trevor King <wking@tremily.us>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants