dnfjson: Add Hash functions to repoConfig and Request

These will be used to generate a unique hash to be used with the cache
of dnf-json results.
This commit is contained in:
Brian C. Lane 2022-08-25 15:37:04 -07:00 committed by Tom Gundersen
parent 35059ca60e
commit e307a8174a
2 changed files with 65 additions and 0 deletions

View file

@ -15,6 +15,7 @@ package dnfjson
import (
"bytes"
"crypto/sha256"
"encoding/json"
"fmt"
"os"
@ -263,6 +264,17 @@ type repoConfig struct {
MetadataExpire string `json:"metadata_expire,omitempty"`
}
// Hash calculates an ID string that uniquely represents a repository
// configuration. The Name and ImageTypeTags fields are not considered in the
// calculation.
// Copied from rpmmd/repository.go
func (r *repoConfig) Hash() string {
bts := func(b bool) string {
return fmt.Sprintf("%T", b)
}
return fmt.Sprintf("%x", sha256.Sum256([]byte(r.BaseURL+r.Metalink+r.MirrorList+r.GPGKey+bts(r.IgnoreSSL)+r.MetadataExpire)))
}
// Helper function for creating a depsolve request payload.
// The request defines a sequence of transactions, each depsolving one of the
// elements of `pkgSets` in the order they appear. The `repoConfigs` are used
@ -422,6 +434,23 @@ type Request struct {
Arguments arguments `json:"arguments"`
}
// Hash returns a hash of the unique aspects of the Request
//nolint:errcheck
func (r *Request) Hash() string {
h := sha256.New()
h.Write([]byte(r.Command))
h.Write([]byte(r.ModulePlatformID))
h.Write([]byte(r.Arch))
for _, repo := range r.Arguments.Repos {
h.Write([]byte(repo.Hash()))
}
h.Write([]byte(fmt.Sprintf("%T", r.Arguments.Search.Latest)))
h.Write([]byte(strings.Join(r.Arguments.Search.Packages, "")))
return fmt.Sprintf("%x", h.Sum(nil))
}
// arguments for a dnf-json request
type arguments struct {
// Repositories to use for depsolving

View file

@ -548,3 +548,39 @@ func TestErrorRepoInfo(t *testing.T) {
})
}
}
func TestRepoConfigHash(t *testing.T) {
rc := repoConfig{
ID: "repoid-1",
Name: "A test repository",
BaseURL: "https://arepourl/",
IgnoreSSL: false,
}
hash := rc.Hash()
assert.Equal(t, 64, len(hash))
rc.BaseURL = "https://adifferenturl/"
assert.NotEqual(t, hash, rc.Hash())
}
func TestRequestHash(t *testing.T) {
solver := NewSolver("f36", "36", "x86_64", "/tmp/cache")
repos := []rpmmd.RepoConfig{
rpmmd.RepoConfig{
Name: "A test repository",
BaseURL: "https://arepourl/",
IgnoreSSL: false,
},
}
req, err := solver.makeDumpRequest(repos)
assert.Nil(t, err)
hash := req.Hash()
assert.Equal(t, 64, len(hash))
req, err = solver.makeSearchRequest(repos, []string{"package0*"})
assert.Nil(t, err)
assert.Equal(t, 64, len(req.Hash()))
assert.NotEqual(t, hash, req.Hash())
}