Skip to content
This repository has been archived by the owner on Sep 9, 2020. It is now read-only.

adding TestSingleSourceCache #756

Merged
merged 4 commits into from
Jul 21, 2017
Merged

adding TestSingleSourceCache #756

merged 4 commits into from
Jul 21, 2017

Conversation

jmank88
Copy link
Collaborator

@jmank88 jmank88 commented Jun 15, 2017

What does this do / why do we need it?

This change adds tests for singleSourceCache against the only current implementation, singleSourceCacheMemory. They are more general than they need to be (e.g. equality funcs, cachedLock/Manifest types), but this is in anticipation of being run against a persistent singleSourceCache as well for #431 (which can't rely on == or reflect.DeepEquals as liberally).

@jmank88
Copy link
Collaborator Author

jmank88 commented Jun 15, 2017

Happy to make this a WIP. Could certainly use some more comments at least, if not more cases.

Copy link
Member

@sdboyer sdboyer left a comment

Choose a reason for hiding this comment

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

i think this is generally heading in a very useful direction! some issues with the equality checks in particular, though.

NewBranch(br).Pair(rev1),
NewVersion(ver).Pair(rev2),
}
sort.Slice(versions, func(i, j int) bool {
Copy link
Member

Choose a reason for hiding this comment

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

1.7 still :(

}

// compareManifests compares two manifests and reports differences as test errors.
func compareManifests(t *testing.T, exp, got Manifest) {
Copy link
Member

Choose a reason for hiding this comment

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

nit: s/exp/want/

{
exp, got := exp.DependencyConstraints(), got.DependencyConstraints()
if !projectConstraintsEqual(exp, got) {
t.Errorf("expected constraints equal to %v but got %v", exp, got)
Copy link
Member

Choose a reason for hiding this comment

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

there's a (WNT):, (GOT): pattern used elsewhere in gps' tests. For consistency's sake, let's continue the pattern.

}
sort.Strings(a.P.Imports)
sort.Strings(b.P.Imports)
if len(a.P.Imports) != len(b.P.Imports) {
Copy link
Member

Choose a reason for hiding this comment

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

nit, but let's sort after the length comparison so that we don't do an unnecessary sort.


// pairedVersionsEqual returns true if the PairedVersions have equal VersionTypes and Strings.
func pairedVersionsEqual(a, b PairedVersion) bool {
return a.Type() == b.Type() && a.String() == b.String()
Copy link
Member

Choose a reason for hiding this comment

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

constraint and version equality are something i've struggled with implementing a few times, as the rabbit hole goes pretty deep. i suppose that doing it with string-based comparisons is a good start, but if we're serious about this then it may entail some more digging in.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I have some ideas to make this one more robust (at least we control all the implementing types, so worst case it is just cumbersome). I'll try to come up with some specific cases that break this approach first though.

Copy link
Member

Choose a reason for hiding this comment

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

👍

it's been a while since i've attempted it, but IIRC, at least part of the problem was that the use cases i was trying to service had differing notions of equality. unfortunately, i can't remember what those use cases were - but, something to keep an eye out for when you look at this.

}

switch b.Intersect(a) {
case a, b:
Copy link
Member

Choose a reason for hiding this comment

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

interesting approach! sadly, i think this will fail if given range constraints from the semver lib, as those contain a slice and thus aren't comparable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

panic: runtime error: comparing uncomparable type semver.rangeConstraint 👎

I'll take another stab at this.

}
}

// compareLocks compares two manifests and reports differences as test errors.
Copy link
Member

Choose a reason for hiding this comment

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

s/manifests/locks/

}

// compareLocks compares two manifests and reports differences as test errors.
func compareLocks(t *testing.T, exp, got Lock) {
Copy link
Member

Choose a reason for hiding this comment

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

why not reuse lock diffing for this?

@sdboyer
Copy link
Member

sdboyer commented Jun 15, 2017

for something this large, please break up later commits so it's easier for me to review the interdiff.

@ibrasho
Copy link
Collaborator

ibrasho commented Jun 26, 2017

Something went the wrong after the merge. 😢

@jmank88
Copy link
Collaborator Author

jmank88 commented Jun 26, 2017

Something went the wrong after the merge. 😢

Yeah, I was trying to preserve the history. Perhaps a proper rebase would have been less jarring. The individual commits are more readable this way, but I can squash it all into a single tidy commit or a new branch with a few separate commits - if either would be easier to review.

Edit: Rebased

@jmank88
Copy link
Collaborator Author

jmank88 commented Jun 26, 2017

Added a Constraint.Equals method.

Notice that semverConstraint.Equals relies on semver.Constraint's Stringer behavior:

// Constraints compose the fmt.Stringer interface. This method is the
// bijective inverse of NewConstraint(): if a string yielded from this
// method is passed to NewConstraint(), a byte-identical instance of the
// original Constraint will be returend.

@jmank88
Copy link
Collaborator Author

jmank88 commented Jul 12, 2017

Rebased

@jmank88 jmank88 closed this Jul 12, 2017
@jmank88 jmank88 reopened this Jul 12, 2017
@jmank88 jmank88 closed this Jul 13, 2017
@jmank88 jmank88 reopened this Jul 13, 2017
@jmank88
Copy link
Collaborator Author

jmank88 commented Jul 13, 2017

codeclimate appears to have lost track of the branch


// compareManifests compares two manifests and reports differences as test errors.
func compareManifests(t *testing.T, want, got Manifest) {
{
Copy link
Member

Choose a reason for hiding this comment

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

huh. i didn't know you could do this. this is just to provide a block scope for want and got to be localized within, right?

Copy link
Collaborator Author

@jmank88 jmank88 Jul 18, 2017

Choose a reason for hiding this comment

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

Yeah, it seemed cleaner than a bunch of 'want- Type' vars.

In general, I've found it handy to isolate small portions of longer functions that aren't candidates for entirely separate functions, if only to help readability regarding variable scope or to give some better scope to a comment than line breaks.

@sdboyer sdboyer closed this Jul 18, 2017
@sdboyer sdboyer reopened this Jul 18, 2017
Copy link
Member

@sdboyer sdboyer left a comment

Choose a reason for hiding this comment

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

equality semantics are the worst

if !ok {
return false
}
return v == v2
Copy link
Member

Choose a reason for hiding this comment

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

this is one of those cases where we the definition of "equality" is really contextualized by how we use it. the default branch property on branchVersion is only set correctly by sourceMgr, not by anything that parses manifests. if we rely on this equals operator in the wrong place, then we have problems.

but, perhaps you intend that to be the difference between equals() and Matches()?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The idea was to have a method for verifying the cache serialization strategy, since == and reflect.DeepEquals are too strict. I have renamed the method to identical, and expanded the doc.

Copy link
Collaborator Author

@jmank88 jmank88 Jul 19, 2017

Choose a reason for hiding this comment

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

the default branch property on branchVersion is only set correctly by sourceMgr, not by anything that parses manifests.

The persistent cache handles this case (and hopefully all the other edge cases!).

@@ -52,6 +52,9 @@ type Constraint interface {
// It also forces Constraint to be a private/sealed interface, which is a
// design goal of the system.
typedString() string

// equals returns true if the constraints are logically equivalent.
Copy link
Member

Choose a reason for hiding this comment

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

Per the other notes in this review, this should be clearer about the semantics of the equality check.

@@ -269,3 +269,12 @@ func (vtu versionTypeUnion) Intersect(c Constraint) Constraint {

return none
}

func (vtu versionTypeUnion) identical(c Constraint) bool {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm having second thoughts about this implementation....

Copy link
Member

Choose a reason for hiding this comment

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

hahaha, yeah, the vtu is a nightmare

Copy link
Collaborator Author

@jmank88 jmank88 Jul 19, 2017

Choose a reason for hiding this comment

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

Expanded to treat them as sets for which each element must have an identical member.

@jmank88 jmank88 closed this Jul 19, 2017
@jmank88 jmank88 reopened this Jul 19, 2017
a, b Constraint
eq bool
}{
{a: NewVersion("test"), b: NewVersion("test"), eq: true},
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can drop the keys here.

const root = "example.com/test"

t.Run("info", func(t *testing.T) {
newSemverConstraint := func(s string) Constraint {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Didn't you already define the same function in internal/gps/constraint_test.go?

// Identical Constraints behave identically for all methods defined by the
// interface. A Constraint is always identical to itself.
//
// Constraints serialized for caching are de-serialized into identical instances.
Copy link
Member

Choose a reason for hiding this comment

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

If the serialization process is stringifying, then this isn't true for branches, because of that default branch prop 😢

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's more complicated than that. The encoding scheme is queued up for a future PR after this one (maybe the next, have to dig it out and rebase).

@sdboyer
Copy link
Member

sdboyer commented Jul 20, 2017

i think this is ready to merge, but i need those test greens first :/

@sdboyer sdboyer closed this Jul 20, 2017
@sdboyer sdboyer reopened this Jul 20, 2017
@jmank88 jmank88 closed this Jul 20, 2017
@jmank88 jmank88 reopened this Jul 20, 2017
@sdboyer
Copy link
Member

sdboyer commented Jul 21, 2017

good enough. in we go! 🎉

@sdboyer sdboyer merged commit 20e2462 into golang:master Jul 21, 2017
@jmank88 jmank88 deleted the source_cache_tests branch February 2, 2018 21:07
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants