diff options
-rw-r--r-- | tvix/default.nix | 2 | ||||
-rw-r--r-- | tvix/nar-bridge/pkg/exporter/export.go | 3 | ||||
-rw-r--r-- | tvix/store/protos/go.mod | 4 | ||||
-rw-r--r-- | tvix/store/protos/go.sum | 13 | ||||
-rw-r--r-- | tvix/store/protos/pathinfo_test.go | 113 |
5 files changed, 131 insertions, 4 deletions
diff --git a/tvix/default.nix b/tvix/default.nix index c35ba733a517..802ec9497fa5 100644 --- a/tvix/default.nix +++ b/tvix/default.nix @@ -108,7 +108,7 @@ in store-protos-go = pkgs.buildGoModule { name = "store-golang"; src = depot.third_party.gitignoreSource ./store/protos; - vendorHash = "sha256-o7moXRxhKxCpsds96sSsHHafKJf2AWhFMu/YdSu+FM4="; + vendorHash = "sha256-L+mHTUYRZu8PSbD7LJ9QRuW1+ImIYbH9/SKgAoL9W8w="; }; # Build the Rust documentation for publishing on docs.tvix.dev. diff --git a/tvix/nar-bridge/pkg/exporter/export.go b/tvix/nar-bridge/pkg/exporter/export.go index 40ccc4b6380c..1f898ccad6dd 100644 --- a/tvix/nar-bridge/pkg/exporter/export.go +++ b/tvix/nar-bridge/pkg/exporter/export.go @@ -194,9 +194,6 @@ func Export( } } -// TODO: add validation functions to Directory in both rust and golang, to -// validate the keys in directories, files and symlinks are sorted. - // drainNextNode will drain a directory message with one of its child nodes, // whichever comes first alphabetically. func drainNextNode(d *castorev1pb.Directory) interface{} { diff --git a/tvix/store/protos/go.mod b/tvix/store/protos/go.mod index 3038b2a6c58c..5c6306f5175a 100644 --- a/tvix/store/protos/go.mod +++ b/tvix/store/protos/go.mod @@ -5,16 +5,20 @@ go 1.19 require ( code.tvl.fyi/tvix/castore/protos v0.0.0-20230922125121-72355662d742 github.com/nix-community/go-nix v0.0.0-20231005143722-b0f8b73c06df + github.com/stretchr/testify v1.8.1 google.golang.org/grpc v1.51.0 google.golang.org/protobuf v1.28.1 ) require ( + github.com/davecgh/go-spew v1.1.1 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/net v0.7.0 // indirect golang.org/x/sys v0.5.0 // indirect golang.org/x/text v0.7.0 // indirect google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.1.7 // indirect ) diff --git a/tvix/store/protos/go.sum b/tvix/store/protos/go.sum index e1840f8d154f..b5b92a74d6fb 100644 --- a/tvix/store/protos/go.sum +++ b/tvix/store/protos/go.sum @@ -4,7 +4,9 @@ code.tvl.fyi/tvix/castore/protos v0.0.0-20230922125121-72355662d742/go.mod h1:Ej github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -31,8 +33,15 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/nix-community/go-nix v0.0.0-20231005143722-b0f8b73c06df h1:n4I26uXUST5vmdsDWPo9ikK57il4htQyhnsLWoHYFmY= github.com/nix-community/go-nix v0.0.0-20231005143722-b0f8b73c06df/go.mod h1:hHM9UK2zOCjvmiLgeaW4LVbOW/vBaRWFJGzfi31/slQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -83,7 +92,11 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= diff --git a/tvix/store/protos/pathinfo_test.go b/tvix/store/protos/pathinfo_test.go new file mode 100644 index 000000000000..adac30a97f88 --- /dev/null +++ b/tvix/store/protos/pathinfo_test.go @@ -0,0 +1,113 @@ +package storev1_test + +import ( + "path" + "testing" + + "github.com/nix-community/go-nix/pkg/storepath" + "github.com/stretchr/testify/assert" + + castorev1pb "code.tvl.fyi/tvix/castore/protos" + storev1pb "code.tvl.fyi/tvix/store/protos" +) + +const ( + EXAMPLE_STORE_PATH = "00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p2017022118243" +) + +var ( + exampleStorePathDigest = []byte{ + 0x8a, 0x12, 0x32, 0x15, 0x22, 0xfd, 0x91, 0xef, 0xbd, 0x60, 0xeb, 0xb2, 0x48, 0x1a, 0xf8, 0x85, + 0x80, 0xf6, 0x16, 0x00} +) + +func genPathInfoSymlink() *storev1pb.PathInfo { + return &storev1pb.PathInfo{ + Node: &castorev1pb.Node{ + Node: &castorev1pb.Node_Symlink{ + Symlink: &castorev1pb.SymlinkNode{ + Name: []byte("00000000000000000000000000000000-dummy"), + Target: []byte("/nix/store/somewhereelse"), + }, + }, + }, + References: [][]byte{exampleStorePathDigest}, + Narinfo: &storev1pb.NARInfo{ + NarSize: 0, + NarSha256: []byte{}, + Signatures: []*storev1pb.NARInfo_Signature{}, + ReferenceNames: []string{EXAMPLE_STORE_PATH}, + }, + } +} + +func genPathInfoSymlinkThin() *storev1pb.PathInfo { + pi := genPathInfoSymlink() + pi.Narinfo = nil + + return pi +} + +func TestValidate(t *testing.T) { + t.Run("happy symlink", func(t *testing.T) { + storePath, err := genPathInfoSymlink().Validate() + assert.NoError(t, err, "PathInfo must validate") + assert.Equal(t, "00000000000000000000000000000000-dummy", storePath.String()) + }) + + t.Run("happy symlink thin", func(t *testing.T) { + storePath, err := genPathInfoSymlinkThin().Validate() + assert.NoError(t, err, "PathInfo must validate") + assert.Equal(t, "00000000000000000000000000000000-dummy", storePath.String()) + }) + + t.Run("invalid reference digest", func(t *testing.T) { + pi := genPathInfoSymlink() + + // create broken references, where the reference digest is wrong + pi.References = append(pi.References, []byte{0x00}) + + _, err := pi.Validate() + assert.Error(t, err, "must not validate") + }) + + t.Run("invalid reference name", func(t *testing.T) { + pi := genPathInfoSymlink() + + // make the reference name an invalid store path + pi.Narinfo.ReferenceNames[0] = "00000000000000000000000000000000-" + + _, err := pi.Validate() + assert.Error(t, err, "must not validate") + }) + + t.Run("reference name digest mismatch", func(t *testing.T) { + pi := genPathInfoSymlink() + + // cause the digest for the reference to mismatch + pi.Narinfo.ReferenceNames[0] = "11111111111111111111111111111111-dummy" + + _, err := pi.Validate() + assert.Error(t, err, "must not validate") + }) + + t.Run("nil root node", func(t *testing.T) { + pi := genPathInfoSymlink() + + pi.Node = nil + + _, err := pi.Validate() + assert.Error(t, err, "must not validate") + }) + + t.Run("invalid root node name", func(t *testing.T) { + pi := genPathInfoSymlink() + + // make the reference name an invalid store path - it may not be absolute + symlinkNode := pi.Node.GetSymlink() + symlinkNode.Name = []byte(path.Join(storepath.StoreDir, "00000000000000000000000000000000-dummy")) + + _, err := pi.Validate() + assert.Error(t, err, "must not validate") + }) +} |