Add func to print string inputs to hashing

Fixes sdboyer/gps#137
This commit is contained in:
sam boyer 2017-01-10 19:24:58 -05:00
Родитель d10c21db71
Коммит b22ce59c60
3 изменённых файлов: 77 добавлений и 10 удалений

26
hash.go
Просмотреть файл

@ -16,14 +16,21 @@ import (
// unnecessary.
//
// (Basically, this is for memoization.)
func (s *solver) HashInputs() []byte {
func (s *solver) HashInputs() (digest []byte) {
buf := new(bytes.Buffer)
s.writeHashingInputs(buf)
hd := sha256.Sum256(buf.Bytes())
digest = hd[:]
return
}
func (s *solver) writeHashingInputs(buf *bytes.Buffer) {
// Apply overrides to the constraints from the root. Otherwise, the hash
// would be computed on the basis of a constraint from root that doesn't
// actually affect solving.
p := s.ovr.overrideAll(s.rm.DependencyConstraints().merge(s.rm.TestDependencyConstraints()))
// Build up a buffer of all the inputs.
buf := new(bytes.Buffer)
for _, pd := range p {
buf.WriteString(string(pd.Ident.ProjectRoot))
buf.WriteString(pd.Ident.Source)
@ -103,9 +110,18 @@ func (s *solver) HashInputs() []byte {
an, av := s.b.AnalyzerInfo()
buf.WriteString(an)
buf.WriteString(av.String())
}
hd := sha256.Sum256(buf.Bytes())
return hd[:]
// HashingInputsAsString returns the raw input data used by Solver.HashInputs()
// as a string.
//
// This is primarily intended for debugging purposes.
func HashingInputsAsString(s Solver) string {
ts := s.(*solver)
buf := new(bytes.Buffer)
ts.writeHashingInputs(buf)
return buf.String()
}
type sortPackageOrErr []PackageOrErr

Просмотреть файл

@ -3,6 +3,7 @@ package gps
import (
"bytes"
"crypto/sha256"
"strings"
"testing"
)
@ -42,7 +43,12 @@ func TestHashInputs(t *testing.T) {
correct := h.Sum(nil)
if !bytes.Equal(dig, correct) {
t.Errorf("Hashes are not equal")
t.Error("Hashes are not equal")
}
fixstr, hisstr := strings.Join(elems, ""), HashingInputsAsString(s)
if fixstr != hisstr {
t.Errorf("Hashing inputs not equal:\n\t(GOT) %s\n\t(WNT) %s", hisstr, fixstr)
}
}
@ -94,6 +100,11 @@ func TestHashInputsReqsIgs(t *testing.T) {
t.Errorf("Hashes are not equal")
}
fixstr, hisstr := strings.Join(elems, ""), HashingInputsAsString(s)
if fixstr != hisstr {
t.Errorf("Hashing inputs not equal:\n\t(GOT) %s\n\t(WNT) %s", hisstr, fixstr)
}
// Add requires
rm.req = map[string]bool{
"baz": true,
@ -137,6 +148,11 @@ func TestHashInputsReqsIgs(t *testing.T) {
t.Errorf("Hashes are not equal")
}
fixstr, hisstr = strings.Join(elems, ""), HashingInputsAsString(s)
if fixstr != hisstr {
t.Errorf("Hashing inputs not equal:\n\t(GOT) %s\n\t(WNT) %s", hisstr, fixstr)
}
// remove ignores, just test requires alone
rm.ig = nil
params.Manifest = rm
@ -173,6 +189,11 @@ func TestHashInputsReqsIgs(t *testing.T) {
if !bytes.Equal(dig, correct) {
t.Errorf("Hashes are not equal")
}
fixstr, hisstr = strings.Join(elems, ""), HashingInputsAsString(s)
if fixstr != hisstr {
t.Errorf("Hashing inputs not equal:\n\t(GOT) %s\n\t(WNT) %s", hisstr, fixstr)
}
}
func TestHashInputsOverrides(t *testing.T) {
@ -224,6 +245,11 @@ func TestHashInputsOverrides(t *testing.T) {
t.Errorf("Hashes are not equal")
}
fixstr, hisstr := strings.Join(elems, ""), HashingInputsAsString(s)
if fixstr != hisstr {
t.Errorf("Hashing inputs not equal:\n\t(GOT) %s\n\t(WNT) %s", hisstr, fixstr)
}
// Override not in root, just with constraint
rm.ovr["d"] = ProjectProperties{
Constraint: NewBranch("foobranch"),
@ -257,6 +283,11 @@ func TestHashInputsOverrides(t *testing.T) {
t.Errorf("Hashes are not equal")
}
fixstr, hisstr = strings.Join(elems, ""), HashingInputsAsString(s)
if fixstr != hisstr {
t.Errorf("Hashing inputs not equal:\n\t(GOT) %s\n\t(WNT) %s", hisstr, fixstr)
}
// Override not in root, both constraint and network name
rm.ovr["e"] = ProjectProperties{
Source: "groucho",
@ -294,6 +325,11 @@ func TestHashInputsOverrides(t *testing.T) {
t.Errorf("Hashes are not equal")
}
fixstr, hisstr = strings.Join(elems, ""), HashingInputsAsString(s)
if fixstr != hisstr {
t.Errorf("Hashing inputs not equal:\n\t(GOT) %s\n\t(WNT) %s", hisstr, fixstr)
}
// Override in root, just constraint
rm.ovr["a"] = ProjectProperties{
Constraint: NewVersion("fluglehorn"),
@ -332,6 +368,11 @@ func TestHashInputsOverrides(t *testing.T) {
t.Errorf("Hashes are not equal")
}
fixstr, hisstr = strings.Join(elems, ""), HashingInputsAsString(s)
if fixstr != hisstr {
t.Errorf("Hashing inputs not equal:\n\t(GOT) %s\n\t(WNT) %s", hisstr, fixstr)
}
// Override in root, only network name
rm.ovr["a"] = ProjectProperties{
Source: "nota",
@ -371,6 +412,11 @@ func TestHashInputsOverrides(t *testing.T) {
t.Errorf("Hashes are not equal")
}
fixstr, hisstr = strings.Join(elems, ""), HashingInputsAsString(s)
if fixstr != hisstr {
t.Errorf("Hashing inputs not equal:\n\t(GOT) %s\n\t(WNT) %s", hisstr, fixstr)
}
// Override in root, network name and constraint
rm.ovr["a"] = ProjectProperties{
Source: "nota",
@ -411,4 +457,9 @@ func TestHashInputsOverrides(t *testing.T) {
if !bytes.Equal(dig, correct) {
t.Errorf("Hashes are not equal")
}
fixstr, hisstr = strings.Join(elems, ""), HashingInputsAsString(s)
if fixstr != hisstr {
t.Errorf("Hashing inputs not equal:\n\t(GOT) %s\n\t(WNT) %s", hisstr, fixstr)
}
}

Просмотреть файл

@ -173,10 +173,10 @@ type solver struct {
// a "lock file" - and/or use it to write out a directory tree of dependencies,
// suitable to be a vendor directory, via CreateVendorTree.
type Solver interface {
// HashInputs produces a hash digest representing the unique inputs to this
// solver. It is guaranteed that, if the hash digest is equal to the digest
// from a previous Solution.InputHash(), that that Solution is valid for
// this Solver's inputs.
// HashInputs hashes the unique inputs to this solver, returning the hash
// digest. It is guaranteed that, if the resulting digest is equal to the
// digest returned from a previous Solution.InputHash(), that that Solution
// is valid for this Solver's inputs.
//
// In such a case, it may not be necessary to run Solve() at all.
HashInputs() []byte