Skip to content

Commit 5a315a8

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

File tree

4 files changed

+156
-32
lines changed

4 files changed

+156
-32
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+
//"github.com/shirou/gopsutil/v4/mem"
14+
)
15+
16+
type Monitor struct {
17+
cancelFunc context.CancelFunc
18+
isRunning bool
19+
mu sync.Mutex
20+
wg sync.WaitGroup
21+
interval time.Duration
22+
}
23+
24+
func NewMonitor(interval time.Duration) *Monitor {
25+
return &Monitor{
26+
interval: interval,
27+
}
28+
}
29+
30+
func (m *Monitor) Start() error {
31+
m.mu.Lock()
32+
defer m.mu.Unlock()
33+
34+
if m.isRunning {
35+
return fmt.Errorf("The collector is running")
36+
}
37+
38+
fmt.Printf("Attempt to start CPU collector, interval: %s", m.interval)
39+
40+
// create a context.WithCancel
41+
ctx, cancel := context.WithCancel(context.Background())
42+
m.cancelFunc = cancel
43+
m.isRunning = true
44+
45+
// stary goroutine
46+
m.wg.Add(1)
47+
go m.collectLoop(ctx)
48+
49+
fmt.Println("CPU collector has been successfully started")
50+
return nil
51+
}
52+
53+
func (m *Monitor) Stop() error {
54+
if !m.isRunning {
55+
return fmt.Errorf("The collector is not running")
56+
}
57+
58+
// call cancle function
59+
if m.cancelFunc != nil {
60+
m.cancelFunc()
61+
}
62+
63+
// clear flag
64+
m.isRunning = false
65+
// wait for goroutine to finish
66+
m.wg.Wait()
67+
fmt.Println("CPU collector has sent a stop signal")
68+
// may need wait a while to stop
69+
return nil
70+
}
71+
72+
func (m *Monitor) collectLoop(ctx context.Context) {
73+
defer m.wg.Done()
74+
75+
fmt.Println("--> collect goroutine start...")
76+
calcInterval := m.interval
77+
78+
for {
79+
// 1. check Context whether be cancled
80+
select {
81+
case <-ctx.Done():
82+
fmt.Println("<-- collect goroutine receive stop signal")
83+
return // exit goroutine
84+
default:
85+
// continue collect data
86+
}
87+
88+
// 2. collect data
89+
totalPercent, err := cpu.Percent(calcInterval, false)
90+
// no need to sleep, calcInterval automatically do it
91+
92+
if err != nil {
93+
fmt.Printf("Error: fail to collect CPU data: %v", err)
94+
time.Sleep(1 * time.Second)
95+
continue
96+
}
97+
98+
if len(totalPercent) > 0 {
99+
data := fmt.Sprintf("[%s], cpu percent: %.2f%%\n",
100+
time.Now().Format("15:04:05"), totalPercent[0])
101+
wd, _ := os.Getwd()
102+
file := filepath.Join(wd, "../test-results/cpu-consume.txt")
103+
util.WriteToFile(data, file)
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: 25 additions & 23 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,10 @@ 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)
270-
}
271-
if err := getMemoryData("Before start"); err != nil {
272-
fmt.Printf("Failed to collect memory data: %v\n", err)
267+
if tag.Name == "@performance" {
268+
getTimestamp("finish")
269+
if err := monitor.Start(); err != nil {
270+
fmt.Printf("Failed to start monitor: %v\n", err)
273271
}
274272
}
275273
}
@@ -398,6 +396,13 @@ func InitializeScenario(s *godog.ScenarioContext) {
398396
}
399397
}
400398

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

403408
return ctx, nil
@@ -579,8 +584,8 @@ func InitializeScenario(s *godog.ScenarioContext) {
579584
EnsureApplicationIsAccessibleViaNodePort)
580585
s.Step(`^persistent volume of size "([^"]*)"GB exists$`,
581586
EnsureVMPartitionSizeCorrect)
582-
s.Step(`^get cpu data "([^"]*)"`,
583-
getCPUdata)
587+
s.Step(`^record timestamp "([^"]*)"`,
588+
getTimestamp)
584589
s.Step(`^get memory data "([^"]*)"`,
585590
getMemoryData)
586591

@@ -1320,20 +1325,6 @@ func deserializeListBlockDeviceCommandOutputToExtractPVSize(lsblkOutput string)
13201325
return diskSize - (lvmSize + 1), nil
13211326
}
13221327

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-
13371328
func getMemoryData(content string) error {
13381329
v, err := mem.VirtualMemory()
13391330
if err != nil {
@@ -1351,3 +1342,14 @@ func getMemoryData(content string) error {
13511342
file := filepath.Join(wd, "../test-results/memory-consume.txt")
13521343
return util.WriteToFile(data, file)
13531344
}
1345+
1346+
func getTimestamp(content string) {
1347+
data := fmt.Sprintf("[%s], %s\n",
1348+
time.Now().Format("15:04:05"), content)
1349+
wd, err := os.Getwd()
1350+
if err != nil {
1351+
fmt.Println("failed to get working directory: %v", err)
1352+
}
1353+
file := filepath.Join(wd, "../test-results/time-stamp.txt")
1354+
util.WriteToFile(data, file)
1355+
}

0 commit comments

Comments
 (0)