Skip to content

Commit 873fdae

Browse files
committed
2 parents 9a53745 + df2ccc6 commit 873fdae

File tree

15 files changed

+319
-125
lines changed

15 files changed

+319
-125
lines changed

CONTRIBUTING.md

Lines changed: 38 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
available through your OS package manager)
3131
- Install [Docker](https://docs.docker.com/install/) and
3232
[Docker Compose](https://docs.docker.com/compose/install/).
33-
- [Install Go 1.13 or above](https://golang.org/doc/install).
33+
- [Install Go 1.22.7 or above](https://golang.org/doc/install).
3434

3535
### Setup Dgraph from source repo
3636

@@ -94,23 +94,29 @@ You can build Dgraph using `make dgraph` or `make install` which add the version
9494
binary.
9595

9696
- `make dgraph`: Creates a `dgraph` binary at `./dgraph/dgraph`
97-
- `make install`: Creates a `dgraph` binary at `$GOPATH/bin/dgraph`. You can add `$GOPATH/bin` to
98-
your `$PATH`.
97+
- `make install`: Creates a `dgraph` binary at `$GOPATH/bin/dgraph`. You should add `$GOPATH/bin` to
98+
your `$PATH` if it isn't there already.
9999

100-
```text
100+
```sh
101101
$ make install
102-
$ dgraph version
103-
[Decoder]: Using assembly version of decoder
104-
105-
Dgraph version : v1.1.1
106-
Dgraph SHA-256 : 97326c9328aff93851290b12d846da81a7da5b843e97d7c63f5d79091b9063c1
107-
Commit SHA-1 : 8994a57
108-
Commit timestamp : 2019-12-16 18:24:50 -0800
109-
Branch : HEAD
110-
Go version : go1.13.5
102+
Installing Dgraph...
103+
Commit SHA256: 15839b156e9920ca2c4ab718e1e73b6637b8ecec
104+
Old SHA256: 596e362ede7466a2569d19ded91241e457e665ada785d05a902af2c6f2cea508
105+
Installed dgraph to /Users/<homedir>/go/bin/dgraph
111106

112-
For Dgraph official documentation, visit https://dgraph.io/docs/.
107+
$ dgraph version
108+
Dgraph version : v24.0.2-103-g15839b156
109+
Dgraph codename : dgraph
110+
Dgraph SHA-256 : 9ce738cd055dfebdef5d68b2a49ea4e062e597799498607dbd1bb618d48861a6
111+
Commit SHA-1 : 15839b156
112+
Commit timestamp : 2025-01-10 17:56:49 -0500
113+
Branch : username/some-branch-that-im-on
114+
Go version : go1.22.7
115+
jemalloc enabled : true
116+
117+
For Dgraph official documentation, visit https://dgraph.io/docs.
113118
For discussions about Dgraph , visit https://discuss.dgraph.io.
119+
For fully-managed Dgraph Cloud , visit https://dgraph.io/cloud.
114120

115121
Licensed variously under the Apache Public License 2.0 and Dgraph Community License.
116122
Copyright 2015-2025 Hypermode Inc.
@@ -119,73 +125,32 @@ Copyright 2015-2025 Hypermode Inc.
119125
### Build Docker Image
120126

121127
```sh
122-
make image
128+
make image-local
123129
```
124130

125-
To build a test Docker image from source, use `make image`. This builds a Dgraph binary using
126-
`make dgraph` and creates a Docker image named `dgraph/dgraph` tagged as the current branch name.
127-
The image only contains the `dgraph` binary.
128-
129-
Example:
130-
131-
```bash
132-
$ git rev-parse --abbrev-ref HEAD # current branch
133-
main
134-
$ make image
135-
Successfully built c74d564d911f
136-
Successfully tagged dgraph/dgraph:main
137-
$ $ docker run --rm -it dgraph/dgraph:main dgraph version
138-
[Decoder]: Using assembly version of decoder
139-
140-
Dgraph version : v1.1.1-1-g5fa139a0e
141-
Dgraph SHA-256 : 31f8c9324eb90a6f4659066937fcebc67bbca251c20b9da0461c2fd148187689
142-
Commit SHA-1 : 5fa139a0e
143-
Commit timestamp : 2019-12-16 20:52:06 -0800
144-
Branch : main
145-
Go version : go1.13.5
146-
147-
For Dgraph official documentation, visit https://dgraph.io/docs/.
148-
For discussions about Dgraph , visit https://discuss.dgraph.io.
149-
150-
Licensed variously under the Apache Public License 2.0 and Dgraph Community License.
151-
Copyright 2015-2025 Hypermode Inc.
152-
```
131+
To build a test Docker image from source, use `make image-local`. This builds a linux-compatible
132+
Dgraph binary using `make dgraph` and creates a Docker image tagged `dgraph/dgraph:local`. You can
133+
then use this local image to test Dgraph in your local Docker setup.
153134

154135
### Testing
155136

156-
#### Dgraph
157-
158-
1. Change directory to t directory.
159-
2. If all packages need to be tested, run make test If only a specific package needs to be tested,
160-
run make test args="--pkg=desired_package_name"
161-
162-
example 1: make test args="--pkg=tok" example 2: make test args="--pkg=tlstest/acl"
163-
164-
The first example will run all the tests in the 'tok' directory (if there are any) The second one
165-
will run all the test in the acl subfolder of the tlstest directory. Note: running make test
166-
args="--pkg=tlstest" will return an error saying no packages found because all the tests in the
167-
tlstest package are in subdirectories of the package. So the subdirectories must be specified as
168-
shown in example 2.
137+
Dgraph employs a ~~complex~~ sophisticated testing framework that includes extensive test coverage.
138+
Due to the comprehensive nature of these tests, a complete test run can take several hours,
139+
depending on your hardware. To manage this complex testing process efficiently, we've developed a
140+
custom test framework implemented in Go, which resides in the [./t](/t) directory. This specialized
141+
framework provides enhanced control and flexibility beyond what's available through standard Go
142+
testing framework.
169143

170-
Tests should be written in Go and use the Dgraph cluster set up in `dgraph/docker-compose.yml`
171-
whenever possible. If the functionality being tested requires a different cluster setup (e.g.
172-
different commandline options), the `*_test.go` files should be put in a separate directory that
173-
also contains a `docker-compose.yml` to set up the cluster as needed.
144+
For dependencies, runner flags and instructions for running tests on non-Linux machines, see the
145+
[README](t/README.md) in the [_t_](t) folder.
174146

175-
**IMPORTANT:** All containers should be labeled with `cluster: test` so they may be correctly
176-
restarted and cleaned up by the test script.
147+
Other integration tests do not use the testing framework located in the `t` folder. Consult the
148+
[github actions definitions](.github) folder to discover the tests we run as part of our continuous
149+
delivery process.
177150

178-
#### Badger
179-
180-
Run `go test` in the root folder.
181-
182-
```bash
183-
$ go test ./...
184-
ok github.com/dgraph-io/badger 24.853s
185-
ok github.com/dgraph-io/badger/skl 0.027s
186-
ok github.com/dgraph-io/badger/table 0.478s
187-
ok github.com/dgraph-io/badger/y 0.004s
188-
```
151+
Non-integration unit tests exist for many core packages that can be exercised without invoking the
152+
testing framework. For instance, to unit test the core DQL parsing package:
153+
`go test github.com/hypermodeinc/dgraph/v24/dql`.
189154

190155
## Contributing
191156

dgraph/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ BUILD_VERSION := $(shell echo ${DGRAPH_VERSION} | sed -e 's/-amd64//' -e 's/-arm
2929
endif
3030

3131
GOOS ?= $(shell go env GOOS)
32+
GOARCH ?= $(shell go env GOARCH)
3233
# Only build with jemalloc on Linux, mac
3334
ifeq ($(GOOS),$(filter $(GOOS),linux darwin))
3435
BUILD_TAGS ?= jemalloc
@@ -72,6 +73,9 @@ INSTALL_TARGET = $(GOPATH)/bin/$(BIN)
7273
ifneq ($(strip $(shell go env GOBIN)),)
7374
INSTALL_TARGET = $(shell go env GOBIN)/$(BIN)
7475
endif
76+
ifneq ($(GOOS)_$(GOARCH),$(shell go env GOHOSTOS)_$(shell go env GOHOSTARCH))
77+
INSTALL_TARGET = $(GOPATH)/bin/$(GOOS)_$(GOARCH)/$(BIN)
78+
endif
7579

7680
.PHONY: all $(BIN)
7781
all: $(BIN)

dgraphtest/image.go

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -182,32 +182,64 @@ func copyBinary(fromDir, toDir, version string) error {
182182
}
183183

184184
func copy(src, dst string) error {
185+
// Validate inputs
186+
if src == "" || dst == "" {
187+
return errors.New("source or destination paths cannot be empty")
188+
}
189+
190+
// Check source file
185191
sourceFileStat, err := os.Stat(src)
186192
if err != nil {
187-
return err
193+
return errors.Wrapf(err, "failed to stat source file: %s", src)
188194
}
189195
if !sourceFileStat.Mode().IsRegular() {
190-
return errors.Wrap(err, fmt.Sprintf("%s is not a regular file", src))
196+
return errors.Errorf("%s is not a regular file", src)
191197
}
192198

199+
// Open source file
193200
source, err := os.Open(src)
194-
srcStat, _ := source.Stat()
195201
if err != nil {
196-
return errors.Wrap(err, fmt.Sprintf("error while opening file [%s]", src))
202+
return errors.Wrapf(err, "failed to open source file: %s", src)
197203
}
198204
defer source.Close()
199205

200-
destination, err := os.Create(dst)
206+
// Create destination directory if it doesn't exist
207+
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
208+
return errors.Wrapf(err, "failed to create destination directory: %s", filepath.Dir(dst))
209+
}
210+
211+
// Create destination file
212+
destination, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, sourceFileStat.Mode())
201213
if err != nil {
202-
return err
214+
return errors.Wrapf(err, "failed to create destination file: %s", dst)
203215
}
204-
defer destination.Close()
205216

206-
if err := os.Chmod(dst, srcStat.Mode()); err != nil {
207-
return err
217+
// Copy the file
218+
if _, err := io.Copy(destination, source); err != nil {
219+
return errors.Wrap(err, "failed to copy file contents")
220+
}
221+
222+
// Ensure data is flushed to disk
223+
if err := destination.Sync(); err != nil {
224+
return errors.Wrap(err, "failed to sync destination file")
208225
}
209-
_, err = io.Copy(destination, source)
210-
return err
226+
227+
// Close the destination file
228+
if err := destination.Close(); err != nil {
229+
return errors.Wrap(err, "failed to close destination file")
230+
}
231+
232+
// Stat the new file to check file size match
233+
destStat, err := os.Stat(dst)
234+
if err != nil {
235+
return errors.Wrapf(err, "failed to stat destination file: %s", dst)
236+
}
237+
if destStat.Size() != sourceFileStat.Size() {
238+
log.Printf("[WARNING] size mismatch after copy of %s to %s: source=%d bytes, destination=%d bytes",
239+
src, dst, sourceFileStat.Size(), destStat.Size())
240+
}
241+
242+
return nil
211243
}
212244

213245
// IsHigherVersion checks whether "higher" is the higher version compared to "lower"

dgraphtest/local_cluster.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ func (c *LocalCluster) HealthCheck(zeroOnly bool) error {
550550
func (c *LocalCluster) containerHealthCheck(url func(c *LocalCluster) (string, error)) error {
551551
endpoint, err := url(c)
552552
if err != nil {
553-
return errors.Wrap(err, "error getting health URL")
553+
return errors.Wrapf(err, "error getting health URL %v", endpoint)
554554
}
555555

556556
for range 60 {
@@ -764,24 +764,41 @@ func (c *LocalCluster) recreateContainers() error {
764764
// Client returns a grpc client that can talk to any Alpha in the cluster
765765
func (c *LocalCluster) Client() (*dgraphapi.GrpcClient, func(), error) {
766766
// TODO(aman): can we cache the connections?
767+
retryPolicy := `{
768+
"methodConfig": [{
769+
"retryPolicy": {
770+
"MaxAttempts": 4,
771+
"InitialBackoff": ".01s",
772+
"MaxBackoff": ".01s",
773+
"BackoffMultiplier": 1.0,
774+
"RetryableStatusCodes": [ "UNAVAILABLE" ]
775+
}
776+
}]
777+
}`
767778
var apiClients []api.DgraphClient
768779
var conns []*grpc.ClientConn
769780
for _, aa := range c.alphas {
770781
if !aa.isRunning {
782+
// QUESTIONS(shivaji): Should this be 'continue' instead of a break from the loop
771783
break
772784
}
773785
url, err := aa.alphaURL(c)
774786
if err != nil {
775787
return nil, nil, errors.Wrap(err, "error getting health URL")
776788
}
777-
conn, err := grpc.Dial(url, grpc.WithTransportCredentials(insecure.NewCredentials()))
789+
conn, err := grpc.Dial(url,
790+
grpc.WithTransportCredentials(insecure.NewCredentials()),
791+
grpc.WithDefaultServiceConfig(retryPolicy))
778792
if err != nil {
779793
return nil, nil, errors.Wrap(err, "error connecting to alpha")
780794
}
781795
conns = append(conns, conn)
782796
apiClients = append(apiClients, api.NewDgraphClient(conn))
783797
}
784798

799+
if len(apiClients) == 0 {
800+
return nil, nil, errors.New("no alphas running")
801+
}
785802
client := dgo.NewDgraphClient(apiClients...)
786803
cleanup := func() {
787804
for _, conn := range conns {

ee/acl/acl_curl_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ func (asuite *AclTestSuite) TestCurlAuthorization() {
5252
// alter and mutate should fail.
5353
queryArgs := func(jwt string) []string {
5454
return []string{"-H", fmt.Sprintf("X-Dgraph-AccessToken:%s", jwt),
55+
"--ipv4",
5556
"-H", "Content-Type: application/dql",
5657
"-d", query, testutil.SockAddrHttp + "/query"}
5758
}

protos/protos_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package protos
1919

2020
import (
2121
"path/filepath"
22+
"runtime"
2223
"testing"
2324

2425
"github.com/stretchr/testify/require"
@@ -27,6 +28,10 @@ import (
2728
)
2829

2930
func TestProtosRegenerate(t *testing.T) {
31+
if runtime.GOOS != "linux" {
32+
t.Skip("Skipping test on non-Linux platform")
33+
}
34+
3035
err := testutil.Exec("make", "regenerate")
3136
require.NoError(t, err, "Got error while regenerating protos: %v\n", err)
3237

systest/audit/audit_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ func TestZeroAudit(t *testing.T) {
3636
nId := state.Zeros["1"].Id
3737
defer os.RemoveAll(fmt.Sprintf("audit_dir/za/zero_audit_0_%s.log", nId))
3838
zeroCmd := map[string][]string{
39-
"/removeNode": {`--location`, "--request", "GET",
39+
"/removeNode": {`--location`, "--request", "GET", "--ipv4",
4040
fmt.Sprintf("%s/removeNode?id=3&group=1", testutil.SockAddrZeroHttp)},
41-
"/assign": {"--location", "--request", "GET",
41+
"/assign": {"--location", "--request", "GET", "--ipv4",
4242
fmt.Sprintf("%s/assign?what=uids&num=100", testutil.SockAddrZeroHttp)},
43-
"/moveTablet": {"--location", "--request", "GET",
43+
"/moveTablet": {"--location", "--request", "GET", "--ipv4",
4444
fmt.Sprintf("%s/moveTablet?tablet=name&group=2", testutil.SockAddrZeroHttp)}}
4545

4646
msgs := make([]string, 0)
@@ -67,22 +67,22 @@ func TestAlphaAudit(t *testing.T) {
6767
}
6868
defer os.Remove(fmt.Sprintf("audit_dir/aa/alpha_audit_1_%s.log", nId))
6969
testCommand := map[string][]string{
70-
"/admin": {"--location", "--request", "POST",
70+
"/admin": {"--location", "--request", "POST", "--ipv4",
7171
fmt.Sprintf("%s/admin", testutil.SockAddrHttp),
7272
"--header", "Content-Type: application/json",
7373
"--data-raw", `'{"query":"mutation {\n backup(
7474
input: {destination: \"/Users/sankalanparajuli/work/backup\"}) {\n response {\n message\n code\n }\n }\n}\n","variables":{}}'`}, //nolint:lll
7575

76-
"/graphql": {"--location", "--request", "POST", fmt.Sprintf("%s/graphql", testutil.SockAddrHttp),
76+
"/graphql": {"--location", "--request", "POST", "--ipv4", fmt.Sprintf("%s/graphql", testutil.SockAddrHttp),
7777
"--header", "Content-Type: application/json",
7878
"--data-raw", `'{"query":"query {\n __schema {\n __typename\n }\n}","variables":{}}'`},
7979

80-
"/alter": {"-X", "POST", fmt.Sprintf("%s/alter", testutil.SockAddrHttp), "-d",
80+
"/alter": {"-X", "POST", "--ipv4", fmt.Sprintf("%s/alter", testutil.SockAddrHttp), "-d",
8181
`name: string @index(term) .
8282
type Person {
8383
name
8484
}`},
85-
"/query": {"-H", "'Content-Type: application/dql'", "-X", "POST", fmt.Sprintf("%s/query", testutil.SockAddrHttp),
85+
"/query": {"-H", "'Content-Type: application/dql'", "-X", "POST", "--ipv4", fmt.Sprintf("%s/query", testutil.SockAddrHttp),
8686
"-d", `$'
8787
{
8888
balances(func: anyofterms(name, "Alice Bob")) {
@@ -92,7 +92,7 @@ input: {destination: \"/Users/sankalanparajuli/work/backup\"}) {\n response {
9292
}
9393
}'`},
9494
"/mutate": {"-H", "'Content-Type: application/rdf'", "-X",
95-
"POST", fmt.Sprintf("%s/mutate?startTs=4", testutil.SockAddrHttp), "-d", `$'
95+
"POST", "--ipv4", fmt.Sprintf("%s/mutate?startTs=4", testutil.SockAddrHttp), "-d", `$'
9696
{
9797
set {
9898
<0x1> <balance> "110" .

0 commit comments

Comments
 (0)