Skip to content

Commit 776af4f

Browse files
committed
[QE]monitor cpu usage in e2e test case
1 parent 8d2c93c commit 776af4f

File tree

4 files changed

+158
-31
lines changed

4 files changed

+158
-31
lines changed

test/e2e/features/story_microshift.feature

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ Feature: Microshift test stories
77
And setting config property "persistent-volume-size" to value "20" succeeds
88
And ensuring network mode user
99
And executing single crc setup command succeeds
10-
And get cpu data "Before start"
1110
And get memory data "Before start"
11+
And record timestamp "start"
1212
And starting CRC with default bundle succeeds
13-
And get cpu data "After start"
1413
And get memory data "After start"
1514
And ensuring oc command is available
1615
And ensuring microshift cluster is fully operational
@@ -22,6 +21,7 @@ Feature: Microshift test stories
2221

2322
@microshift @testdata @linux @windows @darwin @cleanup
2423
Scenario: Start and expose a basic HTTP service and check after restart
24+
And record timestamp "deployment"
2525
Given executing "oc create namespace testproj" succeeds
2626
And executing "oc config set-context --current --namespace=testproj" succeeds
2727
When executing "oc apply -f httpd-example.yaml" succeeds
@@ -40,9 +40,10 @@ Feature: Microshift test stories
4040
And get memory data "After deployment"
4141
Then executing "curl -s http://httpd-example-testproj.apps.crc.testing" succeeds
4242
And stdout should contain "Hello CRC!"
43+
And record timestamp "stop"
4344
When executing "crc stop" succeeds
44-
And get cpu data "After stop"
4545
And get memory data "After stop"
46+
And record timestamp "start again"
4647
And starting CRC with default bundle succeeds
4748
And checking that CRC is running
4849
And with up to "4" retries with wait period of "1m" http response from "http://httpd-example-testproj.apps.crc.testing" has status code "200"

test/e2e/features/story_openshift.feature

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@ Feature: 4 Openshift stories
33

44
Background:
55
Given setting config property "disk-size" to value "40" succeeds
6+
And get memory data "Before start"
7+
And record timestamp "start"
68
And ensuring CRC cluster is running
9+
And get memory data "After start"
10+
And record timestamp "deployment"
711
And ensuring oc command is available
812
And ensuring user is logged in succeeds
913

1014
# End-to-end health check
1115

12-
@darwin @linux @windows @testdata @story_health @needs_namespace
16+
@darwin @linux @windows @testdata @story_health @needs_namespace @performance
1317
Scenario: Overall cluster health
1418
Given executing "oc new-project testproj" succeeds
15-
And get cpu data "After start"
16-
And get memory data "After start"
1719
When executing "oc apply -f httpd-example.yaml" succeeds
1820
And executing "oc rollout status deployment httpd-example" succeeds
1921
Then stdout should contain "successfully rolled out"
@@ -25,14 +27,14 @@ Feature: 4 Openshift stories
2527
Then stdout should contain "httpd-example exposed"
2628
When executing "oc expose svc httpd-example" succeeds
2729
Then stdout should contain "httpd-example exposed"
28-
And get cpu data "After deployment"
29-
And get memory data "After deployment"
3030
When with up to "20" retries with wait period of "5s" http response from "http://httpd-example-testproj.apps-crc.testing" has status code "200"
3131
Then executing "curl -s http://httpd-example-testproj.apps-crc.testing" succeeds
3232
And stdout should contain "Hello CRC!"
33+
And get memory data "After deployment"
34+
And record timestamp "stop"
3335
When executing "crc stop" succeeds
34-
And get cpu data "After stop"
3536
And get memory data "After stop"
37+
And record timestamp "start again"
3638
And starting CRC with default bundle succeeds
3739
And checking that CRC is running
3840
And with up to "4" retries with wait period of "1m" http response from "http://httpd-example-testproj.apps-crc.testing" has status code "200"

test/e2e/testsuite/performance.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package testsuite
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
"sync"
9+
"time"
10+
11+
"github.com/crc-org/crc/v2/test/extended/util"
12+
"github.com/shirou/gopsutil/v4/cpu"
13+
)
14+
15+
type Monitor struct {
16+
cancelFunc context.CancelFunc
17+
isRunning bool
18+
mu sync.Mutex
19+
wg sync.WaitGroup
20+
interval time.Duration
21+
}
22+
23+
func NewMonitor(interval time.Duration) *Monitor {
24+
return &Monitor{
25+
interval: interval,
26+
}
27+
}
28+
29+
func (m *Monitor) Start() error {
30+
m.mu.Lock()
31+
defer m.mu.Unlock()
32+
33+
if m.isRunning {
34+
return fmt.Errorf("The collector is running")
35+
}
36+
37+
fmt.Printf("Attempt to start CPU collector, interval: %s", m.interval)
38+
39+
// create a context.WithCancel
40+
ctx, cancel := context.WithCancel(context.Background())
41+
m.cancelFunc = cancel
42+
m.isRunning = true
43+
44+
// stary goroutine
45+
m.wg.Add(1)
46+
go m.collectLoop(ctx)
47+
48+
fmt.Println("CPU collector has been successfully started")
49+
return nil
50+
}
51+
52+
func (m *Monitor) Stop() error {
53+
m.mu.Lock()
54+
defer m.mu.Unlock()
55+
56+
if !m.isRunning {
57+
return fmt.Errorf("The collector is not running")
58+
}
59+
if m.cancelFunc != nil {
60+
m.cancelFunc()
61+
}
62+
m.isRunning = false
63+
m.wg.Wait()
64+
fmt.Println("CPU collector has sent a stop signal")
65+
// may need wait a while to stop
66+
return nil
67+
}
68+
69+
func (m *Monitor) collectLoop(ctx context.Context) {
70+
defer m.wg.Done()
71+
72+
fmt.Println("--> collect goroutine start...")
73+
calcInterval := m.interval
74+
75+
for {
76+
// 1. check Context whether be cancled
77+
select {
78+
case <-ctx.Done():
79+
fmt.Println("<-- collect goroutine receive stop signal")
80+
return // exit goroutine
81+
default:
82+
// continue collect data
83+
}
84+
85+
// 2. collect data
86+
totalPercent, err := cpu.Percent(calcInterval, false)
87+
// no need to sleep, calcInterval automatically do it
88+
89+
if err != nil {
90+
fmt.Printf("Error: fail to collect CPU data: %v", err)
91+
time.Sleep(1 * time.Second)
92+
continue
93+
}
94+
95+
if len(totalPercent) > 0 {
96+
data := fmt.Sprintf("[%s], cpu percent: %.2f%%\n",
97+
time.Now().Format("15:04:05"), totalPercent[0])
98+
wd, _ := os.Getwd()
99+
file := filepath.Join(wd, "../test-results/cpu-consume.txt")
100+
err := util.WriteToFile(data, file)
101+
if err != nil {
102+
fmt.Printf("Error: fail to write to %s: %v", file, err)
103+
}
104+
}
105+
/*
106+
vMem, err := mem.VirtualMemory()
107+
if err != nil {
108+
fmt.Printf("Error: failed to collect memory data: %v", err)
109+
continue
110+
}
111+
memoryused := vMem.Used / 1024 / 1024
112+
data := fmt.Sprintf("[%s], MemoryUsed(MB): %d\n" ,
113+
time.Now().Format("15:04:05"), memoryused)
114+
wd, _ := os.Getwd()
115+
file := filepath.Join(wd, "../test-results/memory-consume.txt")
116+
util.WriteToFile(data, file)
117+
*/
118+
}
119+
}

test/e2e/testsuite/testsuite.go

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828
crcCmd "github.com/crc-org/crc/v2/test/extended/crc/cmd"
2929
"github.com/crc-org/crc/v2/test/extended/util"
3030
"github.com/cucumber/godog"
31-
"github.com/shirou/gopsutil/v4/cpu"
3231
"github.com/shirou/gopsutil/v4/mem"
3332
"github.com/spf13/pflag"
3433
)
@@ -169,6 +168,7 @@ func InitializeTestSuite(tctx *godog.TestSuiteContext) {
169168
}
170169

171170
func InitializeScenario(s *godog.ScenarioContext) {
171+
monitor := NewMonitor(1 * time.Second)
172172

173173
s.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) {
174174

@@ -264,12 +264,13 @@ func InitializeScenario(s *godog.ScenarioContext) {
264264
}
265265
}
266266

267-
if tag.Name == "@story_health" {
268-
if err := getCPUdata("Before start"); err != nil {
269-
fmt.Printf("Failed to collect CPU data: %v\n", err)
267+
if tag.Name == "@performance" {
268+
err := getTimestamp("finish")
269+
if err != nil {
270+
fmt.Printf("Failed to finish getTimestamp: %v\n", err)
270271
}
271-
if err := getMemoryData("Before start"); err != nil {
272-
fmt.Printf("Failed to collect memory data: %v\n", err)
272+
if err := monitor.Start(); err != nil {
273+
fmt.Printf("Failed to start monitor: %v\n", err)
273274
}
274275
}
275276
}
@@ -398,6 +399,13 @@ func InitializeScenario(s *godog.ScenarioContext) {
398399
}
399400
}
400401

402+
if tag.Name == "@performance" {
403+
if err := monitor.Stop(); err != nil {
404+
fmt.Printf("Failed to stop monitoring: %v\n", err)
405+
}
406+
fmt.Printf("Collection has stopped. Wait for 5 seconds to confirm that the collection task will no longer output data\n")
407+
time.Sleep(5 * time.Second)
408+
}
401409
}
402410

403411
return ctx, nil
@@ -579,8 +587,8 @@ func InitializeScenario(s *godog.ScenarioContext) {
579587
EnsureApplicationIsAccessibleViaNodePort)
580588
s.Step(`^persistent volume of size "([^"]*)"GB exists$`,
581589
EnsureVMPartitionSizeCorrect)
582-
s.Step(`^get cpu data "([^"]*)"`,
583-
getCPUdata)
590+
s.Step(`^record timestamp "([^"]*)"`,
591+
getTimestamp)
584592
s.Step(`^get memory data "([^"]*)"`,
585593
getMemoryData)
586594

@@ -1320,20 +1328,6 @@ func deserializeListBlockDeviceCommandOutputToExtractPVSize(lsblkOutput string)
13201328
return diskSize - (lvmSize + 1), nil
13211329
}
13221330

1323-
func getCPUdata(content string) error {
1324-
cpuData, err := cpu.Percent(0, false)
1325-
if err != nil {
1326-
return fmt.Errorf("failed to get CPU data: %v", err)
1327-
}
1328-
if len(cpuData) == 0 {
1329-
return fmt.Errorf("no CPU data available")
1330-
}
1331-
data := fmt.Sprintf("%s: %.2f%%\n", content, cpuData)
1332-
wd, _ := os.Getwd()
1333-
file := filepath.Join(wd, "../test-results/cpu-consume.txt")
1334-
return util.WriteToFile(data, file)
1335-
}
1336-
13371331
func getMemoryData(content string) error {
13381332
v, err := mem.VirtualMemory()
13391333
if err != nil {
@@ -1351,3 +1345,14 @@ func getMemoryData(content string) error {
13511345
file := filepath.Join(wd, "../test-results/memory-consume.txt")
13521346
return util.WriteToFile(data, file)
13531347
}
1348+
1349+
func getTimestamp(content string) error {
1350+
data := fmt.Sprintf("[%s], %s\n",
1351+
time.Now().Format("15:04:05"), content)
1352+
wd, err := os.Getwd()
1353+
if err != nil {
1354+
fmt.Printf("failed to get working directory: %v\n", err)
1355+
}
1356+
file := filepath.Join(wd, "../test-results/time-stamp.txt")
1357+
return util.WriteToFile(data, file)
1358+
}

0 commit comments

Comments
 (0)