mirror of
https://github.com/hanzoai/graph.git
synced 2026-10-30 18:35:37 +00:00
Derived from Dgraph (github.com/dgraph-io/dgraph) at commit 64804bd2, Apache-2.0. See NOTICE. WHAT THIS IS. The graph engine as a Go library: posting lists, the DQL parser, the type and tokenizer system, the index and schema layers, and the wire types. 39,170 lines of the upstream's 166,337. THE STORE is github.com/luxfi/zapdb, a Badger fork that kept the package name, the subpackages (options, pb, y) and the API — Open, OpenManaged, DB, Options — so the 74 import sites are aliased rather than rewritten. THE CODEC is ZAP. zapdb serializes with ZAP, not protobuf: its pb package builds the ZAP types by default and the protobuf ones only under `-tags grpc`, a path that does not compile (table/builder.go calls pb.Marshal, which that tag removes). One call site in posting needed converting; every other type here is Hanzo's own protobuf and is untouched. NO TRANSPORT. An embedded engine dials nothing, so nothing here imports google.golang.org/grpc. Removed: 20 transport functions in x, the generated service stubs for Raft, Zero and Worker (1,657 lines), and the JWT helper — identity belongs to IAM. The core called none of them. NOT KEPT: worker, conn, raftwal, the cluster commands, the GraphQL layer and the test harnesses. `query`, the DQL execution engine, went with them because it depends on worker; parsing DQL is available here, executing it is not. The history of the upstream project lives at github.com/dgraph-io/dgraph. This repository begins at the derivation because three quarters of that history describes code this fork does not carry.
120 lines
4.9 KiB
Go
120 lines
4.9 KiB
Go
/*
|
|
* SPDX-FileCopyrightText: © 2017-2026 Istari Digital, Inc.
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
package x
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type testTrustKey int
|
|
|
|
const testTrust testTrustKey = iota
|
|
|
|
// ns namespace-attributes a bare name, the way the alter validator and
|
|
// no-schema mutation guard see predicate/type names at the call sites.
|
|
func ns(name string) string { return NamespaceAttr(RootNamespace, name) }
|
|
|
|
func TestReservedNamespaceRegistry(t *testing.T) {
|
|
RegisterReservedNamespace(ReservedNamespace{
|
|
PredicatePrefix: "dgraph.testns.rel.",
|
|
Predicates: []string{"dgraph.testns.xid", "dgraph.testns.cfg"},
|
|
Types: []string{"dgraph.testns.node"},
|
|
ValueLocked: []string{"dgraph.testns.cfg"},
|
|
TrustMarker: testTrust,
|
|
})
|
|
|
|
// Dynamic prefix members.
|
|
require.True(t, IsRegisteredReservedPredicate(ns("dgraph.testns.rel.owner")))
|
|
// Exact predicate members.
|
|
require.True(t, IsRegisteredReservedPredicate(ns("dgraph.testns.xid")))
|
|
require.True(t, IsRegisteredReservedPredicate(ns("dgraph.testns.cfg")))
|
|
// Not owned: a sibling under the same prefix root, a different reserved
|
|
// namespace, and an ordinary predicate.
|
|
require.False(t, IsRegisteredReservedPredicate(ns("dgraph.testns.other")))
|
|
require.False(t, IsRegisteredReservedPredicate(ns("dgraph.graphql.schema")))
|
|
require.False(t, IsRegisteredReservedPredicate(ns("person.name")))
|
|
|
|
// Types are tracked separately from predicates.
|
|
require.True(t, IsRegisteredReservedType(ns("dgraph.testns.node")))
|
|
require.False(t, IsRegisteredReservedType(ns("dgraph.testns.xid"))) // a predicate, not a type
|
|
require.False(t, IsRegisteredReservedType(ns("dgraph.graphql")))
|
|
|
|
// Value lock matches the bare predicate, like IsOtherReservedPredicate.
|
|
// cfg is locked to the registered marker; xid is owned but not locked.
|
|
marker, locked := ReservedPredicateValueLock("dgraph.testns.cfg")
|
|
require.True(t, locked)
|
|
require.Equal(t, testTrust, marker)
|
|
_, locked = ReservedPredicateValueLock("dgraph.testns.xid")
|
|
require.False(t, locked)
|
|
}
|
|
|
|
// TestReservedNamespaceRejectsUnregistered confirms names no namespace claims
|
|
// are never members, so a stock build with no registration keeps the pristine
|
|
// reserved-namespace behavior (only pre-defined names exist under `dgraph.`).
|
|
func TestReservedNamespaceRejectsUnregistered(t *testing.T) {
|
|
require.False(t, IsRegisteredReservedPredicate(ns("dgraph.unregistered.pred")))
|
|
require.False(t, IsRegisteredReservedType(ns("dgraph.unregistered.type")))
|
|
_, locked := ReservedPredicateValueLock("dgraph.unregistered.pred")
|
|
require.False(t, locked)
|
|
}
|
|
|
|
// TestReservedPredicateValueLockCaseInsensitive guards against bypassing a value
|
|
// lock by changing the case of an owned name: ownership is matched
|
|
// case-insensitively, so the value lock must be too.
|
|
func TestReservedPredicateValueLockCaseInsensitive(t *testing.T) {
|
|
RegisterReservedNamespace(ReservedNamespace{
|
|
Predicates: []string{"dgraph.casetest.Secret"},
|
|
ValueLocked: []string{"dgraph.casetest.Secret"},
|
|
TrustMarker: testTrust,
|
|
})
|
|
|
|
for _, p := range []string{"dgraph.casetest.Secret", "dgraph.casetest.secret", "dgraph.casetest.SECRET"} {
|
|
marker, locked := ReservedPredicateValueLock(p)
|
|
require.Truef(t, locked, "value lock must hold regardless of case: %q", p)
|
|
require.Equal(t, testTrust, marker)
|
|
}
|
|
}
|
|
|
|
// TestRegisterReservedNamespaceRequiresTrustMarker confirms the invariant is
|
|
// enforced at registration (init time): ValueLocked without a TrustMarker would
|
|
// make the predicate unwritable by everyone, so it panics rather than failing
|
|
// silently at mutation time.
|
|
func TestRegisterReservedNamespaceRequiresTrustMarker(t *testing.T) {
|
|
require.Panics(t, func() {
|
|
RegisterReservedNamespace(ReservedNamespace{
|
|
Predicates: []string{"dgraph.nomarker.cfg"},
|
|
ValueLocked: []string{"dgraph.nomarker.cfg"},
|
|
// TrustMarker intentionally left nil.
|
|
})
|
|
})
|
|
}
|
|
|
|
// TestRegisterReservedNamespaceRejectsQualifiedName confirms a namespace-qualified
|
|
// name is rejected at registration. The value-lock guard matches the bare
|
|
// predicate, so a qualified entry would never match and the predicate would stay
|
|
// publicly writable — it must fail closed at startup instead.
|
|
func TestRegisterReservedNamespaceRejectsQualifiedName(t *testing.T) {
|
|
require.Panics(t, func() {
|
|
RegisterReservedNamespace(ReservedNamespace{
|
|
Predicates: []string{"dgraph.qualtest.secret"},
|
|
ValueLocked: []string{NamespaceAttr(RootNamespace, "dgraph.qualtest.secret")},
|
|
TrustMarker: testTrust,
|
|
})
|
|
})
|
|
}
|
|
|
|
// TestRegisterReservedNamespaceRejectsDuplicate confirms a name claimed twice
|
|
// panics rather than silently overwriting (for value locks, last-writer-wins
|
|
// would let import order pick the TrustMarker).
|
|
func TestRegisterReservedNamespaceRejectsDuplicate(t *testing.T) {
|
|
require.Panics(t, func() {
|
|
RegisterReservedNamespace(ReservedNamespace{Predicates: []string{"dgraph.duptest.x"}})
|
|
RegisterReservedNamespace(ReservedNamespace{Predicates: []string{"dgraph.duptest.x"}})
|
|
})
|
|
}
|