You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DateKeys/capsule/mutation_test.go

115 lines
3.4 KiB

package capsule_test
import (
"bytes"
"context"
"testing"
"g.activething.com/go/DateKeys/capsule"
"g.activething.com/go/DateKeys/extension"
"g.activething.com/go/DateKeys/internal/testkit"
)
const mutationsFile = "../testdata/vectors/mutations.json"
// build returns a capsule made by testkit.Build and the options to open it.
func build(t *testing.T, b testkit.Build) ([]byte, capsule.OpenOptions) {
t.Helper()
if b.Plaintext == nil {
b.Plaintext = []byte("malicious creator")
}
out, err := b.Make()
if err != nil {
t.Fatal(err)
}
return out.DKC, capsule.OpenOptions{Registry: testkit.Registry(), Source: testkit.NewSource(testkit.Release(1000)), Now: testkit.Fixed(testkit.Genesis().AddDate(1, 0, 0))}
}
// Spec §64: every mutation of the corpus (testkit.Mutations), built afresh,
// fails with its exact normative error at its exact step, and a failure
// before the release request causes no request.
func TestMutationCorpus(t *testing.T) {
e, err := testkit.NewMutationEnv(fixtureDir)
if err != nil {
t.Fatal(err)
}
n := 0
for _, m := range testkit.Mutations() {
if m.Spec {
n++
}
t.Run(m.Name, func(t *testing.T) {
in, err := m.Make(e)
if err != nil {
t.Fatal(err)
}
if err := m.Check(in); err != nil {
t.Fatal(err)
}
})
}
if n != 33 {
t.Fatalf("spec §64 lists 33 mutations, the corpus has %d", n)
}
}
// The exported corpus, testdata/vectors/mutations.json, holds every mutation
// of the corpus in order, and replaying each case from the file alone gives
// exactly the recorded error and step. The capsules that are not built with
// randomness are the ones the corpus derives from the fixtures.
func TestExportedMutationCorpus(t *testing.T) {
var f testkit.MutationFile
if err := testkit.ReadJSON(mutationsFile, &f); err != nil {
t.Fatal(err)
}
e, err := testkit.NewMutationEnv(fixtureDir)
if err != nil {
t.Fatal(err)
}
muts := testkit.Mutations()
if len(f.Cases) != len(muts) {
t.Fatalf("%d exported cases, the corpus has %d mutations", len(f.Cases), len(muts))
}
for i, c := range f.Cases {
m := muts[i]
t.Run(c.Name, func(t *testing.T) {
if c.Name != m.Name || c.Spec != m.Spec || c.Error != m.Want.Code() || c.Step != m.Step || c.Network != m.Network || c.Frozen != m.Random {
t.Fatalf("exported case %+v does not match mutation %q", c, m.Name)
}
if err := c.Check(fixtureDir); err != nil {
t.Fatal(err)
}
if m.Random {
if c.DKC.Base != "" {
t.Fatal("a frozen capsule must not depend on a fixture")
}
return
}
want, err := m.Make(e)
if err != nil {
t.Fatal(err)
}
got, err := c.Input(fixtureDir)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(got.DKC, want.DKC) || !bytes.Equal(got.DKK, want.DKK) {
t.Fatal("the exported capsule or .dkk differs from the one the mutation derives")
}
})
}
}
// Known critical extensions are accepted when the application declares them.
func TestKnownCriticalExtensions(t *testing.T) {
crit := []extension.Extension{{ID: "org.example.must-understand", Version: 1}}
for _, b := range []testkit.Build{{HeaderCritical: crit}, {ControlCritical: crit}} {
dkc, o := build(t, b)
o.Extensions = extension.Set{"org.example.must-understand": {1}}
var out bytes.Buffer
if _, err := capsule.Open(context.Background(), &out, bytes.NewReader(dkc), o); err != nil || out.String() != "malicious creator" {
t.Fatalf("known critical extension rejected: %v", err)
}
}
}

Powered by TurnKey Linux.