github.com/metacurrency/holochain@v0.1.0-alpha-26.0.20200915073418-5c83169c9b5b/validate_test.go (about) 1 package holochain 2 3 import ( 4 "bytes" 5 "fmt" 6 . "github.com/holochain/holochain-proto/hash" 7 . "github.com/smartystreets/goconvey/convey" 8 "strings" 9 "testing" 10 "time" 11 ) 12 13 func TestValidateReceiver(t *testing.T) { 14 d, _, h := PrepareTestChain("test") 15 defer CleanupTestChain(h, d) 16 17 Convey("VALIDATE_PUT_REQUEST should fail if body isn't a ValidateQuery", t, func() { 18 m := h.node.NewMessage(VALIDATE_PUT_REQUEST, "fish") 19 _, err := ValidateReceiver(h, m) 20 So(err.Error(), ShouldEqual, "expected ValidateQuery got string") 21 }) 22 Convey("VALIDATE_PUT_REQUEST should fail if hash doesn't exist", t, func() { 23 hash, _ := NewHash("QmY8Mzg9F69e5P9AoQPYat6x5HEhc1TVGs11tmfNSzkqh2") 24 m := h.node.NewMessage(VALIDATE_PUT_REQUEST, ValidateQuery{H: hash}) 25 _, err := ValidateReceiver(h, m) 26 So(err, ShouldNotBeNil) 27 So(err.Error(), ShouldEqual, "hash not found") 28 }) 29 Convey("VALIDATE_PUT_REQUEST should return entry by hash", t, func() { 30 entry := GobEntry{C: "bogus entry data"} 31 _, hd, err := h.NewEntry(time.Now(), "evenNumbers", &entry) 32 33 m := h.node.NewMessage(VALIDATE_PUT_REQUEST, ValidateQuery{H: hd.EntryLink}) 34 r, err := ValidateReceiver(h, m) 35 So(err, ShouldBeNil) 36 vr := r.(ValidateResponse) 37 So(vr.Type, ShouldEqual, "evenNumbers") 38 So(fmt.Sprintf("%v", vr.Entry), ShouldEqual, fmt.Sprintf("%v", entry)) 39 So(fmt.Sprintf("%v", vr.Header), ShouldEqual, fmt.Sprintf("%v", *hd)) 40 }) 41 Convey("VALIDATE_LINK_REQUEST should fail if body isn't a ValidateQuery", t, func() { 42 m := h.node.NewMessage(VALIDATE_LINK_REQUEST, "fish") 43 _, err := ValidateReceiver(h, m) 44 So(err.Error(), ShouldEqual, "expected ValidateQuery got string") 45 }) 46 Convey("VALIDATE_LINK_REQUEST should fail if hash doesn't exist", t, func() { 47 hash, _ := NewHash("QmY8Mzg9F69e5P9AoQPYat6x5HEhc1TVGs11tmfNSzkqh2") 48 m := h.node.NewMessage(VALIDATE_LINK_REQUEST, ValidateQuery{H: hash}) 49 _, err := ValidateReceiver(h, m) 50 So(err, ShouldNotBeNil) 51 So(err.Error(), ShouldEqual, "hash not found") 52 }) 53 54 entry := GobEntry{C: "bogus entry data"} 55 _, hd, _ := h.NewEntry(time.Now(), "evenNumbers", &entry) 56 hash := hd.EntryLink 57 58 Convey("VALIDATE_LINK_REQUEST should return error if hash isn't a linking entry", t, func() { 59 m := h.node.NewMessage(VALIDATE_LINK_REQUEST, ValidateQuery{H: hash}) 60 _, err := ValidateReceiver(h, m) 61 So(err.Error(), ShouldEqual, "hash not of a linking entry") 62 }) 63 64 Convey("VALIDATE_LINK_REQUEST should return entry by linking entry hash", t, func() { 65 someData := `{"firstName":"Zippy","lastName":"Pinhead"}` 66 e := GobEntry{C: someData} 67 _, phd, _ := h.NewEntry(time.Now(), "profile", &e) 68 profileHash := phd.EntryLink 69 e = GobEntry{C: fmt.Sprintf(`{"Links":[{"Base":"%s","Link":"%s","Tag":"4stars"}]}`, hash.String(), profileHash.String())} 70 _, le, _ := h.NewEntry(time.Now(), "rating", &e) 71 72 m := h.node.NewMessage(VALIDATE_LINK_REQUEST, ValidateQuery{H: le.EntryLink}) 73 r, err := ValidateReceiver(h, m) 74 So(err, ShouldBeNil) 75 vr := r.(ValidateResponse) 76 So(vr.Type, ShouldEqual, "rating") 77 So(fmt.Sprintf("%v", vr.Entry), ShouldEqual, fmt.Sprintf("%v", e)) 78 So(fmt.Sprintf("%v", vr.Header), ShouldEqual, fmt.Sprintf("%v", *le)) 79 }) 80 } 81 82 func TestValidateMakePackage(t *testing.T) { 83 d, _, h := PrepareTestChain("test") 84 defer CleanupTestChain(h, d) 85 var emptyStringList []string 86 87 Convey("it should be able to make a full chain package", t, func() { 88 req := PackagingReq{PkgReqChain: int64(PkgReqChainOptFull)} 89 pkg, err := MakePackage(h, req) 90 So(err, ShouldBeNil) 91 92 var b bytes.Buffer 93 h.chain.MarshalChain(&b, ChainMarshalFlagsOmitDNA, emptyStringList, emptyStringList) 94 So(string(pkg.Chain), ShouldEqual, string(b.Bytes())) 95 }) 96 Convey("it should be able to make a headers only chain package", t, func() { 97 req := PackagingReq{PkgReqChain: int64(PkgReqChainOptHeaders)} 98 pkg, err := MakePackage(h, req) 99 So(err, ShouldBeNil) 100 101 var b bytes.Buffer 102 h.chain.MarshalChain(&b, ChainMarshalFlagsNoEntries+ChainMarshalFlagsOmitDNA, emptyStringList, emptyStringList) 103 So(string(pkg.Chain), ShouldEqual, string(b.Bytes())) 104 }) 105 Convey("it should be able to make an entries only chain package", t, func() { 106 req := PackagingReq{PkgReqChain: int64(PkgReqChainOptEntries)} 107 pkg, err := MakePackage(h, req) 108 So(err, ShouldBeNil) 109 110 var b bytes.Buffer 111 h.chain.MarshalChain(&b, ChainMarshalFlagsNoHeaders+ChainMarshalFlagsOmitDNA, emptyStringList, emptyStringList) 112 So(string(pkg.Chain), ShouldEqual, string(b.Bytes())) 113 }) 114 115 Convey("it should be able to make package of a chain of just a few types", t, func() { 116 entry := GobEntry{C: "2"} 117 h.NewEntry(time.Now(), "evenNumbers", &entry) 118 entry = GobEntry{C: "3"} 119 h.NewEntry(time.Now(), "oddNumbers", &entry) 120 121 req := PackagingReq{PkgReqChain: int64(PkgReqChainOptFull), PkgReqEntryTypes: []string{"oddNumbers"}} 122 pkg, err := MakePackage(h, req) 123 So(err, ShouldBeNil) 124 125 var b bytes.Buffer 126 h.chain.MarshalChain(&b, ChainMarshalFlagsOmitDNA, []string{"oddNumbers"}, emptyStringList) 127 So(string(pkg.Chain), ShouldEqual, string(b.Bytes())) 128 }) 129 130 Convey("it should not contain the real contents of private entries", t, func() { 131 entry := GobEntry{C: "secret message"} 132 h.NewEntry(time.Now(), "privateData", &entry) 133 134 req := PackagingReq{PkgReqChain: int64(PkgReqChainOptFull)} 135 pkg, err := MakePackage(h, req) 136 So(err, ShouldBeNil) 137 138 _, c1, err := UnmarshalChain(h.hashSpec, bytes.NewBuffer(pkg.Chain)) 139 So(err, ShouldBeNil) 140 So(c1.Entries[2].Content(), ShouldEqual, "2") //from previous test cases 141 So(c1.Entries[3].Content(), ShouldEqual, "3") //from previous test cases 142 So(c1.Entries[4].Content(), ShouldNotEqual, "secret message") 143 So(c1.Entries[4].Content(), ShouldEqual, ChainMarshalPrivateEntryRedacted) 144 }) 145 146 } 147 148 func TestGetValidationResponse(t *testing.T) { 149 d, _, h := PrepareTestChain("test") 150 defer CleanupTestChain(h, d) 151 var emptyStringList []string 152 153 hash := commit(h, "oddNumbers", "3") 154 155 Convey("entry types should return packages based on definition", t, func() { 156 entry, _, err := h.chain.GetEntry(hash) 157 if err != nil { 158 panic(err) 159 } 160 a := NewPutAction("oddNumbers", entry, &Header{}) 161 resp, err := h.GetValidationResponse(a, hash) 162 So(err, ShouldBeNil) 163 So(resp.Type, ShouldEqual, "oddNumbers") 164 So(fmt.Sprintf("%v", &resp.Entry), ShouldEqual, fmt.Sprintf("%v", entry)) 165 var b bytes.Buffer 166 h.chain.MarshalChain(&b, ChainMarshalFlagsOmitDNA, emptyStringList, emptyStringList) 167 So(fmt.Sprintf("%v", string(resp.Package.Chain)), ShouldEqual, fmt.Sprintf("%v", string(b.Bytes()))) 168 }) 169 170 Convey("it should fail on the DNA (can't validate DNA as it's what determines what's valid)", t, func() { 171 entry, _, err := h.chain.GetEntry(h.dnaHash) 172 a := NewPutAction(AgentEntryType, entry, &Header{}) 173 _, err = h.GetValidationResponse(a, h.dnaHash) 174 So(err, ShouldEqual, ErrNotValidForDNAType) 175 176 }) 177 178 Convey("agent entry type should return the type chain in the package", t, func() { 179 entry, _, err := h.chain.GetEntry(h.agentHash) 180 a := NewPutAction(AgentEntryType, entry, &Header{}) 181 resp, err := h.GetValidationResponse(a, h.agentHash) 182 So(err, ShouldBeNil) 183 So(resp.Type, ShouldEqual, AgentEntryType) 184 So(fmt.Sprintf("%v", &resp.Entry), ShouldEqual, fmt.Sprintf("%v", entry)) 185 186 types := []string{AgentEntryType} 187 var b bytes.Buffer 188 h.chain.MarshalChain(&b, ChainMarshalFlagsOmitDNA, types, emptyStringList) 189 So(fmt.Sprintf("%v", string(resp.Package.Chain)), ShouldEqual, fmt.Sprintf("%v", string(b.Bytes()))) 190 }) 191 192 Convey("key entry type should return empty package with pubkey as entry", t, func() { 193 hash := HashFromPeerID(h.nodeID) 194 a := NewPutAction(KeyEntryType, nil, &Header{}) 195 resp, err := h.GetValidationResponse(a, hash) 196 So(err, ShouldBeNil) 197 So(resp.Type, ShouldEqual, KeyEntryType) 198 199 pk, err := h.agent.EncodePubKey() 200 if err != nil { 201 panic(err) 202 } 203 204 So(string(resp.Entry.Content().(string)), ShouldEqual, pk) 205 So(fmt.Sprintf("%v", resp.Package), ShouldEqual, fmt.Sprintf("%v", Package{})) 206 }) 207 208 Convey("headers entry type should return empty package with the entry", t, func() { 209 hd := h.Chain().Top() 210 j, _ := hd.ToJSON() 211 entryStr := fmt.Sprintf(`[{"Header":%s,"Role":"someRole","Source":"%s"}]`, j, h.nodeID.Pretty()) 212 hash := commit(h, HeadersEntryType, entryStr) 213 hd = h.Chain().Top() 214 e := &GobEntry{C: entryStr} 215 a := NewPutAction(HeadersEntryType, e, hd) 216 resp, err := h.GetValidationResponse(a, hash) 217 So(err, ShouldBeNil) 218 So(resp.Type, ShouldEqual, HeadersEntryType) 219 So(fmt.Sprintf("%v", resp.Entry.Content()), ShouldEqual, entryStr) 220 So(fmt.Sprintf("%v", resp.Package), ShouldEqual, fmt.Sprintf("%v", Package{})) 221 }) 222 } 223 224 func TestMakeValidatePackage(t *testing.T) { 225 d, _, h := PrepareTestChain("test") 226 defer CleanupTestChain(h, d) 227 228 entry := GobEntry{C: `{"firstName":"Zippy","lastName":"Pinhead"}`} 229 h.NewEntry(time.Now().Round(0), "evenNumbers", &entry) 230 231 pkg, _ := MakePackage(h, PackagingReq{PkgReqChain: int64(PkgReqChainOptFull)}) 232 Convey("it should be able to make a validate package", t, func() { 233 vpkg, err := MakeValidationPackage(h, &pkg) 234 So(err, ShouldBeNil) 235 So(fmt.Sprintf("%v", vpkg.Chain), ShouldEqual, fmt.Sprintf("%v", h.chain)) 236 }) 237 238 Convey("it should return an error if the package data was tweaked", t, func() { 239 // tweak the agent header 240 pkg.Chain = []byte(strings.Replace(string(pkg.Chain), "%agent", "!agent", -1)) 241 vpkg, err := MakeValidationPackage(h, &pkg) 242 So(err, ShouldNotBeNil) 243 So(vpkg, ShouldBeNil) 244 245 // restore 246 pkg.Chain = []byte(strings.Replace(string(pkg.Chain), "!agent", "%agent", -1)) 247 248 // tweak 249 pkg.Chain = []byte(strings.Replace(string(pkg.Chain), "Zippy", "Zappy", -1)) 250 251 vpkg, err = MakeValidationPackage(h, &pkg) 252 So(err, ShouldNotBeNil) 253 254 }) 255 }