Skip to content

Commit 773b44f

Browse files
authored
Tracetest (#142)
* Add integration tests for trace functionality Signed-off-by: Ondrej Fabry <[email protected]> * Add README for integration tests Signed-off-by: Ondrej Fabry <[email protected]> * Skip old trace tests Signed-off-by: Ondrej Fabry <[email protected]> * Update README.md Signed-off-by: Ondrej Fabry <[email protected]> * Update README.md Signed-off-by: Ondrej Fabry <[email protected]> * Update README.md Signed-off-by: Ondrej Fabry <[email protected]> --------- Signed-off-by: Ondrej Fabry <[email protected]>
1 parent 35c6fa2 commit 773b44f

File tree

6 files changed

+206
-1
lines changed

6 files changed

+206
-1
lines changed

Diff for: core/trace_test.go

+10
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import (
1616
)
1717

1818
func TestTraceEnabled(t *testing.T) {
19+
t.Skipf("these randomly fail, see integration tests")
20+
1921
ctx := setupTest(t, false)
2022
defer ctx.teardownTest()
2123

@@ -62,6 +64,8 @@ func TestTraceEnabled(t *testing.T) {
6264
}
6365

6466
func TestMultiRequestTraceEnabled(t *testing.T) {
67+
t.Skipf("these randomly fail, see integration tests")
68+
6569
ctx := setupTest(t, false)
6670
defer ctx.teardownTest()
6771

@@ -122,6 +126,8 @@ func TestMultiRequestTraceEnabled(t *testing.T) {
122126
}
123127

124128
func TestTraceDisabled(t *testing.T) {
129+
t.Skipf("these randomly fail, see integration tests")
130+
125131
ctx := setupTest(t, false)
126132
defer ctx.teardownTest()
127133

@@ -151,6 +157,8 @@ func TestTraceDisabled(t *testing.T) {
151157
}
152158

153159
func TestTracePerChannel(t *testing.T) {
160+
t.Skipf("these randomly fail, see integration tests")
161+
154162
ctx := setupTest(t, false)
155163
defer ctx.teardownTest()
156164

@@ -238,6 +246,8 @@ func TestTracePerChannel(t *testing.T) {
238246
}
239247

240248
func TestTraceClear(t *testing.T) {
249+
t.Skipf("these randomly fail, see integration tests")
250+
241251
ctx := setupTest(t, false)
242252
defer ctx.teardownTest()
243253

Diff for: test/integration/README.md

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
Integration Tests
2+
=================
3+
4+
The GoVPP integration testing suite runs each test case against real VPP instance.
5+
6+
The integration tests cases are grouped by files:
7+
- `binapi` - runs tests for VPP API
8+
- `examples` - run examples as tests
9+
- `stats` - runs tests for VPP Stats
10+
- `trace` - runs tests for VPP API trace
11+
- `*` (*other*) - runs specialized tests
12+
13+
## Running Tests
14+
15+
The recommended way to run the integration tests is to use a self-contained testing environment, which is managed from a helper bash script [`run_integration.sh`](../run_integration.sh). The script will build a special Docker image that includes testing suite and other requirements (e.g. VPP, gotestsum..) and then will run the integration tests inside a container.
16+
17+
```shell
18+
make test-integration
19+
```
20+
21+
This will run the tests against latest VPP release by default. To run against specific VPP version, add `VPP_REPO=<REPO>` where `<REPO>` is name of VPP repostiroy on packagecloud.
22+
23+
```shell
24+
# Run against specific VPP version
25+
make test-integration VPP_REPO=2306
26+
27+
# Run against VPP master branch
28+
make test-integration VPP_REPO=master
29+
```
30+
31+
The make target above simply runs a helper script which accepts additional arguments that are passed down directly to `go test ...`.
32+
33+
```shell
34+
# Usage:
35+
# ./test/integration/run_integration.sh <ARGS>
36+
37+
# Run with verbose mode
38+
./test/integration/run_integration.sh -test.v
39+
```
40+
41+
### Run Specific Test Case
42+
43+
To run a specific integration test case(s):
44+
45+
```shell
46+
./test/integration/run_integration.sh -test.run="Interfaces"
47+
```
48+
49+
## Running Tests on your Host
50+
51+
If the script `run_integration.sh` is not used to run tests and the test cases
52+
are directly used, the tests will try to start/stop VPP instance for each test
53+
case individually.
54+
55+
> **Warning**
56+
> This method requires VPP to be installed on your host system.
57+
58+
```shell
59+
TEST=integration go test ./test/integration
60+
```

Diff for: test/integration/binapi_test.go

+52
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@ package integration
1616

1717
import (
1818
"context"
19+
"io"
1920
"testing"
2021

22+
interfaces "go.fd.io/govpp/binapi/interface"
2123
"go.fd.io/govpp/binapi/vpe"
2224
"go.fd.io/govpp/test/vpptesting"
2325
)
2426

27+
// TestVersion tests that getting VPP version works.
2528
func TestVersion(t *testing.T) {
2629
test := vpptesting.SetupVPP(t)
2730

@@ -37,3 +40,52 @@ func TestVersion(t *testing.T) {
3740
t.Fatal("expected VPP version to not be empty")
3841
}
3942
}
43+
44+
// TestInterfacesLoopback tests that creating a loopback interface works and returns
45+
// non-zero ID and that the interface will be listed in interface dump.
46+
func TestInterfacesLoopback(t *testing.T) {
47+
test := vpptesting.SetupVPP(t)
48+
ctx := context.Background()
49+
50+
ifacesRPC := interfaces.NewServiceClient(test.Conn)
51+
52+
// create loopback interface
53+
reply, err := ifacesRPC.CreateLoopback(ctx, &interfaces.CreateLoopback{})
54+
if err != nil {
55+
t.Fatal("interfaces.CreateLoopback error:", err)
56+
}
57+
loopId := reply.SwIfIndex
58+
t.Logf("loopback interface created (id: %v)", reply.SwIfIndex)
59+
60+
// list interfaces
61+
stream, err := ifacesRPC.SwInterfaceDump(ctx, &interfaces.SwInterfaceDump{})
62+
if err != nil {
63+
t.Fatal("interfaces.SwInterfaceDump error:", err)
64+
}
65+
66+
t.Log("Dumping interfaces")
67+
foundLoop := false
68+
numIfaces := 0
69+
for {
70+
iface, err := stream.Recv()
71+
if err == io.EOF {
72+
break
73+
}
74+
if err != nil {
75+
t.Fatal("interfaces.SwInterfaceDump/Recv error:", err)
76+
}
77+
numIfaces++
78+
t.Logf("- interface[%d]: %q\n", iface.SwIfIndex, iface.InterfaceName)
79+
if iface.SwIfIndex == loopId {
80+
foundLoop = true
81+
}
82+
}
83+
84+
// verify expected
85+
if !foundLoop {
86+
t.Fatalf("loopback interface (id: %v) not found", loopId)
87+
}
88+
if numIfaces != 2 {
89+
t.Errorf("expected 2 interfaces in dump, got %d", numIfaces)
90+
}
91+
}

Diff for: test/integration/examples_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import (
2424
)
2525

2626
func TestExamples(t *testing.T) {
27+
skipTestIfGoNotInstalled(t)
28+
2729
if err := filepath.WalkDir("./examples", func(path string, d fs.DirEntry, err error) error {
2830
if !d.IsDir() || filepath.Base(d.Name()) == "examples" {
2931
return nil

Diff for: test/integration/main_test.go

+17-1
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,28 @@
1717
package integration
1818

1919
import (
20+
"fmt"
2021
"os"
22+
"os/exec"
2123
"testing"
2224
)
2325

26+
var (
27+
// IntegrationTestsActive is set to true if integration tests should run.
28+
IntegrationTestsActive = os.Getenv("TEST") == "integration"
29+
)
30+
2431
func TestMain(m *testing.M) {
25-
if os.Getenv("TEST") == "integration" {
32+
if IntegrationTestsActive {
2633
os.Exit(m.Run())
2734
}
35+
fmt.Fprintf(os.Stderr, "integration tests are NOT enabled (set TEST='integration' to enable)\n")
36+
os.Exit(0)
37+
}
38+
39+
func skipTestIfGoNotInstalled(t *testing.T) {
40+
_, err := exec.LookPath("go")
41+
if err != nil {
42+
t.Skipf("`go` command is not available, skipping test")
43+
}
2844
}

Diff for: test/integration/trace_test.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) 2023 Cisco and/or its affiliates.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at:
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package integration
16+
17+
import (
18+
"context"
19+
"fmt"
20+
"testing"
21+
22+
"go.fd.io/govpp/api"
23+
"go.fd.io/govpp/binapi/vpe"
24+
"go.fd.io/govpp/test/vpptesting"
25+
)
26+
27+
func TestTrace(t *testing.T) {
28+
test := vpptesting.SetupVPP(t)
29+
30+
test.Conn.Trace().Enable(true)
31+
32+
runTraceRequests(t, test)
33+
34+
records := test.Conn.Trace().GetRecords()
35+
36+
if len(records) != 2 {
37+
t.Fatalf("expected 2 records, got %d", len(records))
38+
}
39+
40+
printTraceRecords(t, records)
41+
}
42+
43+
func printTraceRecords(t *testing.T, records []*api.Record) {
44+
t.Logf("API trace (records: %d):\n", len(records))
45+
t.Logf("--------------------\n")
46+
for _, item := range records {
47+
h, m, s := item.Timestamp.Clock()
48+
reply := ""
49+
if item.IsReceived {
50+
reply = "(reply)"
51+
}
52+
fmt.Printf("%dh:%dm:%ds:%dns %s %s\n", h, m, s,
53+
item.Timestamp.Nanosecond(), item.Message.GetMessageName(), reply)
54+
}
55+
t.Logf("--------------------\n")
56+
}
57+
58+
func runTraceRequests(t *testing.T, test *vpptesting.TestCtx) {
59+
vpeRPC := vpe.NewServiceClient(test.Conn)
60+
61+
_, err := vpeRPC.ShowVersion(context.Background(), &vpe.ShowVersion{})
62+
if err != nil {
63+
t.Fatalf("getting version failed: %v", err)
64+
}
65+
}

0 commit comments

Comments
 (0)