Skip to content

Commit

Permalink
Added integration tests
Browse files Browse the repository at this point in the history
Signed-off-by: ItalyPaleAle <43508+ItalyPaleAle@users.noreply.github.com>
  • Loading branch information
ItalyPaleAle committed Oct 18, 2023
1 parent bb9eb57 commit 5644f7c
Show file tree
Hide file tree
Showing 10 changed files with 473 additions and 26 deletions.
19 changes: 16 additions & 3 deletions tests/integration/framework/process/daprd/daprd.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package daprd
import (
"context"
"fmt"
"net"
"net/http"
"os"
"path/filepath"
Expand Down Expand Up @@ -155,6 +156,18 @@ func (d *Daprd) Cleanup(t *testing.T) {
d.appHTTP.Cleanup(t)
}

func (d *Daprd) WaitUntilTCPReady(t *testing.T, ctx context.Context) {
assert.Eventually(t, func() bool {
dialer := net.Dialer{Timeout: time.Second}
net, err := dialer.DialContext(ctx, "tcp", "localhost:"+strconv.Itoa(d.HTTPPort()))
if err != nil {
return false
}
net.Close()
return true
}, 10*time.Second, 100*time.Millisecond)
}

func (d *Daprd) WaitUntilRunning(t *testing.T, ctx context.Context) {
client := util.HTTPClient(t)
assert.Eventually(t, func() bool {
Expand All @@ -168,7 +181,7 @@ func (d *Daprd) WaitUntilRunning(t *testing.T, ctx context.Context) {
}
defer resp.Body.Close()
return http.StatusNoContent == resp.StatusCode
}, time.Second*10, 100*time.Millisecond)
}, 10*time.Second, 100*time.Millisecond)
}

func (d *Daprd) WaitUntilAppHealth(t *testing.T, ctx context.Context) {
Expand All @@ -185,7 +198,7 @@ func (d *Daprd) WaitUntilAppHealth(t *testing.T, ctx context.Context) {
}
defer resp.Body.Close()
return http.StatusNoContent == resp.StatusCode
}, time.Second*10, 100*time.Millisecond)
}, 10*time.Second, 100*time.Millisecond)
}
if d.appProtocol == "grpc" {
assert.Eventually(t, func() bool {
Expand All @@ -203,7 +216,7 @@ func (d *Daprd) WaitUntilAppHealth(t *testing.T, ctx context.Context) {
out := runtimev1pb.HealthCheckResponse{}
err = conn.Invoke(ctx, "/dapr.proto.runtime.v1.AppCallbackHealthCheck/HealthCheck", &in, &out)
return err == nil
}, time.Second*10, 100*time.Millisecond)
}, 10*time.Second, 100*time.Millisecond)
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/integration/suite/actors/actors.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ import (
_ "github.com/dapr/dapr/tests/integration/suite/actors/grpc"
_ "github.com/dapr/dapr/tests/integration/suite/actors/healthz"
_ "github.com/dapr/dapr/tests/integration/suite/actors/http"
_ "github.com/dapr/dapr/tests/integration/suite/actors/metadata"
_ "github.com/dapr/dapr/tests/integration/suite/actors/reminders"
)
12 changes: 1 addition & 11 deletions tests/integration/suite/actors/healthz/healthz.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ package healthz

import (
"context"
"net"
"net/http"
"strconv"
"testing"
Expand Down Expand Up @@ -87,16 +86,7 @@ spec:

func (h *healthz) Run(t *testing.T, ctx context.Context) {
h.place.WaitUntilRunning(t, ctx)

assert.Eventually(t, func() bool {
dialer := net.Dialer{Timeout: time.Second}
net, err := dialer.DialContext(ctx, "tcp", "localhost:"+strconv.Itoa(h.daprd.HTTPPort()))
if err != nil {
return false
}
net.Close()
return true
}, time.Second*5, time.Millisecond*100)
h.daprd.WaitUntilTCPReady(t, ctx)

select {
case <-h.healthzCalled:
Expand Down
12 changes: 1 addition & 11 deletions tests/integration/suite/actors/healthz/initerror.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ package healthz

import (
"context"
"net"
"net/http"
"strconv"
"testing"
Expand Down Expand Up @@ -92,16 +91,7 @@ spec:

func (i *initerror) Run(t *testing.T, ctx context.Context) {
i.place.WaitUntilRunning(t, ctx)

assert.Eventually(t, func() bool {
dialer := net.Dialer{Timeout: time.Second}
net, err := dialer.DialContext(ctx, "tcp", "localhost:"+strconv.Itoa(i.daprd.HTTPPort()))
if err != nil {
return false
}
net.Close()
return true
}, time.Second*5, time.Millisecond*100)
i.daprd.WaitUntilTCPReady(t, ctx)

client := util.HTTPClient(t)

Expand Down
101 changes: 101 additions & 0 deletions tests/integration/suite/actors/metadata/actor_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
Copyright 2023 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implieh.
See the License for the specific language governing permissions and
limitations under the License.
*/

package metadata

import (
"context"
"net/http"
"strconv"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/dapr/dapr/tests/integration/framework"
"github.com/dapr/dapr/tests/integration/framework/process/daprd"
prochttp "github.com/dapr/dapr/tests/integration/framework/process/http"
"github.com/dapr/dapr/tests/integration/framework/process/placement"
"github.com/dapr/dapr/tests/integration/framework/util"
"github.com/dapr/dapr/tests/integration/suite"
)

func init() {
suite.Register(new(metadataActorClient))
}

// metadataActorClient tests the response of the metadata API for a healthy actor client.
type metadataActorClient struct {
daprd *daprd.Daprd
place *placement.Placement
blockConfig chan struct{}
}

func (m *metadataActorClient) Setup(t *testing.T) []framework.Option {
m.blockConfig = make(chan struct{})

handler := http.NewServeMux()
handler.HandleFunc("/dapr/config", func(w http.ResponseWriter, r *http.Request) {
<-m.blockConfig
w.Write([]byte(`{"entities": []}`))
})
handler.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
handler.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`OK`))
})

srv := prochttp.New(t, prochttp.WithHandler(handler))
m.place = placement.New(t)
m.daprd = daprd.New(t,
daprd.WithPlacementAddresses("localhost:"+strconv.Itoa(m.place.Port())),
daprd.WithAppProtocol("http"),
daprd.WithAppPort(srv.Port()),
daprd.WithLogLevel("info"), // Daprd is super noisy in debug mode when connecting to placement.
)

return []framework.Option{
framework.WithProcesses(m.place, srv, m.daprd),
}
}

func (m *metadataActorClient) Run(t *testing.T, ctx context.Context) {
// Test an app that is an actor client (no actor state store configured)
// 1. Assert that status is "INITIALIZING" before /dapr/config is called
// 2. After init is done, status is "RUNNING", hostReady is "false", placement reports a connection, and hosted actors are empty

m.place.WaitUntilRunning(t, ctx)
m.daprd.WaitUntilTCPReady(t, ctx)

client := util.HTTPClient(t)

// Before initialization
res := getMetadata(t, ctx, client, m.daprd.HTTPPort())
require.False(t, t.Failed())
assert.Equal(t, "INITIALIZING", res.ActorRuntime.RuntimeStatus)
assert.False(t, res.ActorRuntime.HostReady)
assert.Empty(t, res.ActorRuntime.Placement)
assert.Empty(t, res.ActorRuntime.ActiveActors)

// Complete init
close(m.blockConfig)
assert.EventuallyWithT(t, func(t *assert.CollectT) {
res := getMetadata(t, ctx, client, m.daprd.HTTPPort())
assert.Equal(t, "RUNNING", res.ActorRuntime.RuntimeStatus)
assert.False(t, res.ActorRuntime.HostReady)
assert.Equal(t, "placement: connected", res.ActorRuntime.Placement)
assert.Empty(t, res.ActorRuntime.ActiveActors, 0)
}, 10*time.Second, 100*time.Millisecond)
}
76 changes: 76 additions & 0 deletions tests/integration/suite/actors/metadata/actor_disabled.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright 2023 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implieh.
See the License for the specific language governing permissions and
limitations under the License.
*/

package metadata

import (
"context"
"net/http"
"testing"
"time"

"github.com/stretchr/testify/assert"

"github.com/dapr/dapr/tests/integration/framework"
"github.com/dapr/dapr/tests/integration/framework/process/daprd"
prochttp "github.com/dapr/dapr/tests/integration/framework/process/http"
"github.com/dapr/dapr/tests/integration/framework/util"
"github.com/dapr/dapr/tests/integration/suite"
)

func init() {
suite.Register(new(metadataActorDisabled))
}

// metadataActorDisabled tests the response of the metadata API when the actor runtime is disabled
type metadataActorDisabled struct {
daprd *daprd.Daprd
}

func (m *metadataActorDisabled) Setup(t *testing.T) []framework.Option {
handler := http.NewServeMux()
handler.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
handler.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`OK`))
})

srv := prochttp.New(t, prochttp.WithHandler(handler))
m.daprd = daprd.New(t, // "WithPlacementAddress" is missing on purpose, to disable the actor runtime
daprd.WithResourceFiles(stateStore),
daprd.WithAppProtocol("http"),
daprd.WithAppPort(srv.Port()),
daprd.WithLogLevel("info"), // Daprd is super noisy in debug mode when connecting to placement.
)

return []framework.Option{
framework.WithProcesses(srv, m.daprd),
}
}

func (m *metadataActorDisabled) Run(t *testing.T, ctx context.Context) {
// Test an app that has the actor runtime disabled (when there's no placement address)

m.daprd.WaitUntilTCPReady(t, ctx)

client := util.HTTPClient(t)

assert.EventuallyWithT(t, func(t *assert.CollectT) {
res := getMetadata(t, ctx, client, m.daprd.HTTPPort())
assert.Equal(t, "DISABLED", res.ActorRuntime.RuntimeStatus)
assert.False(t, res.ActorRuntime.HostReady)
assert.Empty(t, res.ActorRuntime.Placement)
assert.Empty(t, res.ActorRuntime.ActiveActors)
}, 10*time.Second, 100*time.Millisecond)
}
105 changes: 105 additions & 0 deletions tests/integration/suite/actors/metadata/actor_host.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
Copyright 2023 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implieh.
See the License for the specific language governing permissions and
limitations under the License.
*/

package metadata

import (
"context"
"net/http"
"strconv"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/dapr/dapr/tests/integration/framework"
"github.com/dapr/dapr/tests/integration/framework/process/daprd"
prochttp "github.com/dapr/dapr/tests/integration/framework/process/http"
"github.com/dapr/dapr/tests/integration/framework/process/placement"
"github.com/dapr/dapr/tests/integration/framework/util"
"github.com/dapr/dapr/tests/integration/suite"
)

func init() {
suite.Register(new(metadataActorHost))
}

// metadataActorHost tests the response of the metadata API for a healthy actor host.
type metadataActorHost struct {
daprd *daprd.Daprd
place *placement.Placement
blockConfig chan struct{}
}

func (m *metadataActorHost) Setup(t *testing.T) []framework.Option {
m.blockConfig = make(chan struct{})

handler := http.NewServeMux()
handler.HandleFunc("/dapr/config", func(w http.ResponseWriter, r *http.Request) {
<-m.blockConfig
w.Write([]byte(`{"entities": ["myactortype"]}`))
})
handler.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
handler.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`OK`))
})

srv := prochttp.New(t, prochttp.WithHandler(handler))
m.place = placement.New(t)
m.daprd = daprd.New(t,
daprd.WithResourceFiles(stateStore),
daprd.WithPlacementAddresses("localhost:"+strconv.Itoa(m.place.Port())),
daprd.WithAppProtocol("http"),
daprd.WithAppPort(srv.Port()),
daprd.WithLogLevel("info"), // Daprd is super noisy in debug mode when connecting to placement.
)

return []framework.Option{
framework.WithProcesses(m.place, srv, m.daprd),
}
}

func (m *metadataActorHost) Run(t *testing.T, ctx context.Context) {
// Test an app that is an actor host
// 1. Assert that status is "INITIALIZING" before /dapr/config is called
// 2. After init is done, status is "RUNNING", hostReady is "true", placement reports a connection, and hosted actors are listed

m.place.WaitUntilRunning(t, ctx)
m.daprd.WaitUntilTCPReady(t, ctx)

client := util.HTTPClient(t)

// Before initialization
res := getMetadata(t, ctx, client, m.daprd.HTTPPort())
require.False(t, t.Failed())
assert.Equal(t, "INITIALIZING", res.ActorRuntime.RuntimeStatus)
assert.False(t, res.ActorRuntime.HostReady)
assert.Empty(t, res.ActorRuntime.Placement)
assert.Empty(t, res.ActorRuntime.ActiveActors)

// Complete init
close(m.blockConfig)
assert.EventuallyWithT(t, func(t *assert.CollectT) {
res := getMetadata(t, ctx, client, m.daprd.HTTPPort())
assert.Equal(t, "RUNNING", res.ActorRuntime.RuntimeStatus)
assert.True(t, res.ActorRuntime.HostReady)
assert.Equal(t, "placement: connected", res.ActorRuntime.Placement)
if assert.Len(t, res.ActorRuntime.ActiveActors, 1) {
assert.Equal(t, "myactortype", res.ActorRuntime.ActiveActors[0].Type)
assert.Equal(t, 0, res.ActorRuntime.ActiveActors[0].Count)
}
}, 10*time.Second, 100*time.Millisecond)
}

0 comments on commit 5644f7c

Please sign in to comment.