diff --git a/cloud/bmaas/bmdb/reflection_test.go b/cloud/bmaas/bmdb/reflection_test.go
new file mode 100644
index 0000000..73aa397
--- /dev/null
+++ b/cloud/bmaas/bmdb/reflection_test.go
@@ -0,0 +1,209 @@
+package bmdb
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/google/uuid"
+
+	"source.monogon.dev/cloud/bmaas/bmdb/model"
+	"source.monogon.dev/cloud/bmaas/bmdb/reflection"
+)
+
+// TestReflection exercises the BMDB reflection schema reflection and data
+// retrieval code. Ideally this code would live in //cloud/bmaas/bmdb/reflection,
+// but due to namespacing issues it lives here.
+func TestReflection(t *testing.T) {
+	b := dut()
+	conn, err := b.Open(true)
+	if err != nil {
+		t.Fatalf("Open failed: %v", err)
+	}
+
+	ctx, ctxC := context.WithCancel(context.Background())
+	defer ctxC()
+
+	sess, err := conn.StartSession(ctx)
+	if err != nil {
+		t.Fatalf("StartSession: %v", err)
+	}
+
+	// Create 10 test machines.
+	var mids []uuid.UUID
+	sess.Transact(ctx, func(q *model.Queries) error {
+		for i := 0; i < 10; i += 1 {
+			mach, err := q.NewMachine(ctx)
+			if err != nil {
+				return err
+			}
+			err = q.MachineAddProvided(ctx, model.MachineAddProvidedParams{
+				MachineID:  mach.MachineID,
+				Provider:   model.ProviderEquinix,
+				ProviderID: fmt.Sprintf("test-%d", i),
+			})
+			if err != nil {
+				return err
+			}
+			mids = append(mids, mach.MachineID)
+		}
+		return nil
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+	// Start and fail work on one of the machines with an hour long backoff.
+	w, err := sess.Work(ctx, model.ProcessUnitTest1, func(q *model.Queries) ([]uuid.UUID, error) {
+		return mids[0:1], nil
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+	to := time.Hour
+	w.Fail(ctx, &to, "failure test")
+
+	// On another machine, create a failure with a 1 second backoff.
+	w, err = sess.Work(ctx, model.ProcessUnitTest1, func(q *model.Queries) ([]uuid.UUID, error) {
+		return mids[1:2], nil
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+	to = time.Second
+	w.Fail(ctx, &to, "failure test")
+	// Later on in the test we must wait for this backoff to actually elapse. Start
+	// counting now.
+	elapsed := time.NewTicker(to * 1)
+	defer elapsed.Stop()
+
+	// On another machine, create work and don't finish it yet.
+	_, err = sess.Work(ctx, model.ProcessUnitTest1, func(q *model.Queries) ([]uuid.UUID, error) {
+		return mids[2:3], nil
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	schema, err := conn.Reflect(ctx)
+	if err != nil {
+		t.Fatalf("ReflectTagTypes: %v", err)
+	}
+
+	// Dump all in strict mode.
+	opts := &reflection.GetMachinesOpts{
+		Strict: true,
+	}
+	res, err := schema.GetMachines(ctx, opts)
+	if err != nil {
+		t.Fatalf("Dump failed: %v", err)
+	}
+	if res.Query == "" {
+		t.Errorf("Query not set on result")
+	}
+	machines := res.Data
+	if want, got := 10, len(machines); want != got {
+		t.Fatalf("Expected %d machines in dump, got %d", want, got)
+	}
+
+	// Expect Provided tag on all machines. Do a detailed check on fields, too.
+	for _, machine := range machines {
+		tag, ok := machine.Tags["Provided"]
+		if !ok {
+			t.Errorf("No Provided tag on machine.")
+			continue
+		}
+		if want, got := "Provided", tag.Type.Name(); want != got {
+			t.Errorf("Provided tag should have type %q, got %q", want, got)
+		}
+		if provider := tag.Field("provider"); provider != nil {
+			if want, got := provider.HumanValue(), "Equinix"; want != got {
+				t.Errorf("Wanted Provided.provider value %q, got %q", want, got)
+			}
+		} else {
+			t.Errorf("Provider tag has no provider field")
+		}
+		if providerId := tag.Field("provider_id"); providerId != nil {
+			if !strings.HasPrefix(providerId.HumanValue(), "test-") {
+				t.Errorf("Unexpected provider_id value %q", providerId.HumanValue())
+			}
+		} else {
+			t.Errorf("Provider tag has no provider_id field")
+		}
+	}
+
+	// Now just dump one machine.
+	opts.FilterMachine = &mids[0]
+	res, err = schema.GetMachines(ctx, opts)
+	if err != nil {
+		t.Fatalf("Dump failed: %v", err)
+	}
+	machines = res.Data
+	if want, got := 1, len(machines); want != got {
+		t.Fatalf("Expected %d machines in dump, got %d", want, got)
+	}
+	if want, got := mids[0].String(), machines[0].ID.String(); want != got {
+		t.Fatalf("Expected machine %s, got %s", want, got)
+	}
+
+	// Now dump a machine that doesn't exist. That should just return an empty list.
+	fakeMid := uuid.New()
+	opts.FilterMachine = &fakeMid
+	res, err = schema.GetMachines(ctx, opts)
+	if err != nil {
+		t.Fatalf("Dump failed: %v", err)
+	}
+	machines = res.Data
+	if want, got := 0, len(machines); want != got {
+		t.Fatalf("Expected %d machines in dump, got %d", want, got)
+	}
+
+	// Finally, check the special case machines. The first one should have an active
+	// backoff.
+	opts.FilterMachine = &mids[0]
+	res, err = schema.GetMachines(ctx, opts)
+	if err != nil {
+		t.Errorf("Dump failed: %v", err)
+	} else {
+		machine := res.Data[0]
+		if _, ok := machine.Backoffs["UnitTest1"]; !ok {
+			t.Errorf("Expected UnitTest1 backoff on machine")
+		}
+	}
+	// The second one should have an expired backoff that shouldn't be reported in a
+	// normal call..
+	<-elapsed.C
+	opts.FilterMachine = &mids[1]
+	res, err = schema.GetMachines(ctx, opts)
+	if err != nil {
+		t.Errorf("Dump failed: %v", err)
+	} else {
+		machine := res.Data[0]
+		if _, ok := machine.Backoffs["UnitTest1"]; ok {
+			t.Errorf("Expected no UnitTest1 backoff on machine")
+		}
+	}
+	// But if we ask for expired backoffs, we should get it.
+	opts.ExpiredBackoffs = true
+	res, err = schema.GetMachines(ctx, opts)
+	if err != nil {
+		t.Errorf("Dump failed: %v", err)
+	} else {
+		machine := res.Data[0]
+		if _, ok := machine.Backoffs["UnitTest1"]; !ok {
+			t.Errorf("Expected UnitTest1 backoff on machine")
+		}
+	}
+	// Finally, the third machine should have an active Work item.
+	opts.FilterMachine = &mids[2]
+	res, err = schema.GetMachines(ctx, opts)
+	if err != nil {
+		t.Errorf("Dump failed: %v", err)
+	} else {
+		machine := res.Data[0]
+		if _, ok := machine.Work["UnitTest1"]; !ok {
+			t.Errorf("Expected UnitTest1 work item on machine")
+		}
+	}
+}
