Skip to content

Commit 4016768

Browse files
committed
Merge branch 'master' into verkle-support
2 parents b418fc4 + f9a09b7 commit 4016768

File tree

12 files changed

+483
-158
lines changed

12 files changed

+483
-158
lines changed

cmd/root.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ var rootCmd = &cobra.Command{
2626
logr.Fatal(err)
2727
}
2828

29+
if maxConcurrentTests > 0 {
30+
config.Coordinator.MaxConcurrentTests = maxConcurrentTests
31+
}
32+
2933
if logFormat == "json" {
3034
logr.SetFormatter(&logrus.JSONFormatter{})
3135
logr.Info("Log format set to json")
@@ -37,7 +41,7 @@ var rootCmd = &cobra.Command{
3741
logr.SetLevel(logrus.DebugLevel)
3842
}
3943

40-
coord := coordinator.NewCoordinator(config, logr, metricsPort, maxConcurrentTests)
44+
coord := coordinator.NewCoordinator(config, logr, metricsPort)
4145

4246
if err := coord.Run(cmd.Context()); err != nil {
4347
logr.Fatal(err)
@@ -51,7 +55,7 @@ var (
5155
logFormat string
5256
verbose bool
5357
metricsPort int
54-
maxConcurrentTests int
58+
maxConcurrentTests uint64
5559
version bool
5660
)
5761

@@ -70,7 +74,7 @@ func init() {
7074
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file")
7175
rootCmd.PersistentFlags().StringVar(&logFormat, "log-format", "text", "log format (default is text). Valid values are 'text', 'json'")
7276
rootCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Verbose output")
73-
rootCmd.Flags().IntVar(&maxConcurrentTests, "maxConcurrentTests", 1, "Number of tests to run concurrently")
77+
rootCmd.Flags().Uint64Var(&maxConcurrentTests, "maxConcurrentTests", 0, "Number of tests to run concurrently")
7478
rootCmd.Flags().IntVarP(&metricsPort, "metrics-port", "", 9090, "Port to serve Prometheus metrics on")
7579
rootCmd.Flags().BoolVarP(&version, "version", "", false, "Print version information")
7680
}

pkg/coordinator/config.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"os"
55

66
"github.com/ethpandaops/assertoor/pkg/coordinator/clients"
7+
"github.com/ethpandaops/assertoor/pkg/coordinator/human-duration"
78
"github.com/ethpandaops/assertoor/pkg/coordinator/names"
89
"github.com/ethpandaops/assertoor/pkg/coordinator/types"
910
web_types "github.com/ethpandaops/assertoor/pkg/coordinator/web/types"
@@ -23,13 +24,25 @@ type Config struct {
2324
// Global variables
2425
GlobalVars map[string]interface{} `yaml:"globalVars" json:"globalVars"`
2526

27+
// Coordinator config
28+
Coordinator *CoordinatorConfig `yaml:"coordinator" json:"coordinator"`
29+
2630
// List of Test configurations.
2731
Tests []*types.TestConfig `yaml:"tests" json:"tests"`
2832

2933
// List of yaml files with test configurations
3034
ExternalTests []*types.ExternalTestConfig `yaml:"externalTests" json:"externalTests"`
3135
}
3236

37+
//nolint:revive // ignore
38+
type CoordinatorConfig struct {
39+
// Maximum number of tests executed concurrently
40+
MaxConcurrentTests uint64 `yaml:"maxConcurrentTests" json:"maxConcurrentTests"`
41+
42+
// Test history cleanup delay
43+
TestRetentionTime human.Duration `yaml:"testRetentionTime" json:"testRetentionTime"`
44+
}
45+
3346
// DefaultConfig represents a sane-default configuration.
3447
func DefaultConfig() *Config {
3548
return &Config{
@@ -41,6 +54,7 @@ func DefaultConfig() *Config {
4154
},
4255
},
4356
GlobalVars: make(map[string]interface{}),
57+
Coordinator: &CoordinatorConfig{},
4458
Tests: []*types.TestConfig{},
4559
ExternalTests: []*types.ExternalTestConfig{},
4660
}

pkg/coordinator/coordinator.go

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ type Coordinator struct {
4747
testHistory []types.Test
4848
testRegistryMutex sync.RWMutex
4949
testNotificationChan chan bool
50-
maxConcurrentTests int
5150
}
5251

5352
type testDescriptorEntry struct {
@@ -56,7 +55,7 @@ type testDescriptorEntry struct {
5655
index uint64
5756
}
5857

59-
func NewCoordinator(config *Config, log logrus.FieldLogger, metricsPort, maxConcurrentTests int) *Coordinator {
58+
func NewCoordinator(config *Config, log logrus.FieldLogger, metricsPort int) *Coordinator {
6059
return &Coordinator{
6160
log: logger.NewLogger(&logger.ScopeOptions{
6261
Parent: log,
@@ -70,15 +69,14 @@ func NewCoordinator(config *Config, log logrus.FieldLogger, metricsPort, maxConc
7069
testQueue: []types.Test{},
7170
testHistory: []types.Test{},
7271
testNotificationChan: make(chan bool, 1),
73-
maxConcurrentTests: maxConcurrentTests,
7472
}
7573
}
7674

7775
// Run executes the coordinator until completion.
7876
func (c *Coordinator) Run(ctx context.Context) error {
7977
defer func() {
8078
if err := recover(); err != nil {
81-
logrus.WithError(err.(error)).Errorf("uncaught panic in coordinator.Run: %v, stack: %v", err, string(debug.Stack()))
79+
c.log.GetLogger().WithError(err.(error)).Errorf("uncaught panic in coordinator.Run: %v, stack: %v", err, string(debug.Stack()))
8280
}
8381
}()
8482

@@ -137,6 +135,9 @@ func (c *Coordinator) Run(ctx context.Context) error {
137135
// start test scheduler
138136
go c.runTestScheduler(ctx)
139137

138+
// start test cleanup routine
139+
go c.runTestCleanup(ctx)
140+
140141
// run tests
141142
c.runTestExecutionLoop(ctx)
142143

@@ -345,7 +346,12 @@ func (c *Coordinator) createTestRun(descriptor types.TestDescriptor, configOverr
345346
}
346347

347348
func (c *Coordinator) runTestExecutionLoop(ctx context.Context) {
348-
semaphore := make(chan bool, c.maxConcurrentTests)
349+
concurrencyLimit := c.Config.Coordinator.MaxConcurrentTests
350+
if concurrencyLimit < 1 {
351+
concurrencyLimit = 1
352+
}
353+
354+
semaphore := make(chan bool, concurrencyLimit)
349355

350356
for {
351357
var nextTest types.Test
@@ -393,6 +399,12 @@ func (c *Coordinator) runTest(ctx context.Context, testRef types.Test) {
393399
}
394400

395401
func (c *Coordinator) runTestScheduler(ctx context.Context) {
402+
defer func() {
403+
if err := recover(); err != nil {
404+
c.log.GetLogger().WithError(err.(error)).Panicf("uncaught panic in coordinator.runTestScheduler: %v, stack: %v", err, string(debug.Stack()))
405+
}
406+
}()
407+
396408
// startup scheduler
397409
for _, testDescr := range c.getStartupTests() {
398410
_, err := c.ScheduleTest(testDescr, nil, false)
@@ -480,3 +492,49 @@ func (c *Coordinator) getCronTests(cronTime time.Time) []types.TestDescriptor {
480492

481493
return descriptors
482494
}
495+
496+
func (c *Coordinator) runTestCleanup(ctx context.Context) {
497+
defer func() {
498+
if err := recover(); err != nil {
499+
c.log.GetLogger().WithError(err.(error)).Panicf("uncaught panic in coordinator.runTestCleanup: %v, stack: %v", err, string(debug.Stack()))
500+
}
501+
}()
502+
503+
retentionTime := c.Config.Coordinator.TestRetentionTime.Duration
504+
if retentionTime <= 0 {
505+
retentionTime = 14 * 24 * time.Hour
506+
}
507+
508+
cleanupInterval := 1 * time.Hour
509+
if retentionTime <= 4*time.Hour {
510+
cleanupInterval = 10 * time.Minute
511+
}
512+
513+
for {
514+
select {
515+
case <-ctx.Done():
516+
return
517+
case <-time.After(cleanupInterval):
518+
}
519+
520+
c.cleanupTestHistory(retentionTime)
521+
}
522+
}
523+
524+
func (c *Coordinator) cleanupTestHistory(retentionTime time.Duration) {
525+
c.testRegistryMutex.Lock()
526+
defer c.testRegistryMutex.Unlock()
527+
528+
cleanedHistory := []types.Test{}
529+
530+
for _, test := range c.testHistory {
531+
if test.Status() != types.TestStatusPending && test.StartTime().Add(retentionTime).Compare(time.Now()) == -1 {
532+
test.Logger().Infof("cleanup test")
533+
continue
534+
}
535+
536+
cleanedHistory = append(cleanedHistory, test)
537+
}
538+
539+
c.testHistory = cleanedHistory
540+
}

pkg/coordinator/web/handlers/index.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type IndexPageTestDescriptor struct {
2424

2525
type TestRunData struct {
2626
RunID uint64 `json:"run_id"`
27+
TestID string `json:"test_id"`
2728
Index uint64 `json:"index"`
2829
Name string `json:"name"`
2930
IsStarted bool `json:"started"`
@@ -113,6 +114,7 @@ func (fh *FrontendHandler) getIndexPageData() (*IndexPage, error) {
113114
func (fh *FrontendHandler) getTestRunData(idx int, test types.Test) *TestRunData {
114115
testData := &TestRunData{
115116
RunID: test.RunID(),
117+
TestID: test.TestID(),
116118
Index: uint64(idx),
117119
Name: test.Name(),
118120
StartTime: test.StartTime(),

pkg/coordinator/web/handlers/test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"github.com/ethpandaops/assertoor/pkg/coordinator/web"
1010
"github.com/gorilla/mux"
1111
"github.com/sirupsen/logrus"
12-
"gopkg.in/yaml.v3"
1312
)
1413

1514
type TestPage struct {
@@ -110,12 +109,12 @@ func (fh *FrontendHandler) getTestPageData(testID string) (*TestPage, error) {
110109
}
111110

112111
if testConfig.Config != nil {
113-
testCfgYaml, err := yaml.Marshal(testConfig.Config)
112+
testCfgJSON, err := json.Marshal(testConfig.Config)
114113
if err != nil {
115114
return nil, fmt.Errorf("failed marshalling test config: %v", err)
116115
}
117116

118-
pageData.Config = string(testCfgYaml)
117+
pageData.Config = string(testCfgJSON)
119118
}
120119

121120
// test runs

pkg/coordinator/web/handlers/test_run.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ type TestRunPage struct {
3030
type TestRunTask struct {
3131
Index uint64 `json:"index"`
3232
ParentIndex uint64 `json:"parent_index"`
33-
IndentPx uint64 `json:"indent_px"`
33+
GraphLevels []uint64 `json:"graph_levels"`
3434
Name string `json:"name"`
3535
Title string `json:"title"`
3636
IsStarted bool `json:"started"`
@@ -157,7 +157,7 @@ func (fh *FrontendHandler) getTestRunPageData(runID int64) (*TestRunPage, error)
157157
if taskScheduler != nil && taskScheduler.GetTaskCount() > 0 {
158158
indentationMap := map[uint64]int{}
159159

160-
for _, task := range taskScheduler.GetAllTasks() {
160+
for idx, task := range taskScheduler.GetAllTasks() {
161161
taskStatus := taskScheduler.GetTaskStatus(task)
162162

163163
taskData := &TestRunTask{
@@ -171,6 +171,7 @@ func (fh *FrontendHandler) getTestRunPageData(runID int64) (*TestRunPage, error)
171171
StopTime: taskStatus.StopTime,
172172
Timeout: task.Timeout(),
173173
HasTimeout: task.Timeout() > 0,
174+
GraphLevels: []uint64{},
174175
}
175176

176177
indentation := 0
@@ -179,7 +180,27 @@ func (fh *FrontendHandler) getTestRunPageData(runID int64) (*TestRunPage, error)
179180
}
180181

181182
indentationMap[taskData.Index] = indentation
182-
taskData.IndentPx = uint64(20 * indentation)
183+
184+
if indentation > 0 {
185+
for i := 0; i < indentation; i++ {
186+
taskData.GraphLevels = append(taskData.GraphLevels, 0)
187+
}
188+
189+
taskData.GraphLevels[indentation-1] = 3
190+
191+
for i := idx - 1; i >= 0; i-- {
192+
if pageData.Tasks[i].ParentIndex == taskData.ParentIndex {
193+
pageData.Tasks[i].GraphLevels[indentation-1] = 2
194+
break
195+
}
196+
197+
if pageData.Tasks[i].Index == taskData.ParentIndex {
198+
break
199+
}
200+
201+
pageData.Tasks[i].GraphLevels[indentation-1] = 1
202+
}
203+
}
183204

184205
switch {
185206
case !taskStatus.IsStarted:

pkg/coordinator/web/static/css/layout.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
body main {
33
display: flex;
4-
overflow: hidden;
4+
/* overflow: hidden; */
55
min-height: calc(100vh - 64px)!important;
66
}
77

@@ -69,6 +69,10 @@ main .sidebar {
6969
background-color: rgba(var(--bs-emphasis-color-rgb), 0.03);
7070
}
7171

72+
main .sidebar .nav-pills {
73+
--bs-nav-pills-link-active-bg: rgba(13, 110, 253, 0.7);
74+
}
75+
7276
main .sidebar .nav-link {
7377
color: var(--bs-body-color);
7478
}

pkg/coordinator/web/templates/_layout/layout.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
<link rel="preload" as="font" href="/webfonts/fa-brands-400.woff2" crossorigin />
2525
<link id="app-style" rel="stylesheet" href="/css/layout.css" />
2626
{{ template "css" .Data }}
27+
<script src="/js/jquery.min.js"></script>
28+
<script src="/js/bootstrap.bundle.min.js"></script>
29+
<script src="/js/color-modes.js"></script>
2730
{{ if .ShowSidebar }}
2831
<style>
2932
.main-navigation {
@@ -51,9 +54,6 @@
5154
</div>
5255
</main>
5356

54-
<script src="/js/jquery.min.js"></script>
55-
<script src="/js/bootstrap.bundle.min.js"></script>
56-
<script src="/js/color-modes.js"></script>
5757
<script src="/js/clipboard.min.js"></script>
5858
<script src="/js/assertoor.js"></script>
5959
{{ template "js" .Data }}

pkg/coordinator/web/templates/sidebar/sidebar.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@
77
</div>
88
</div>
99
<div class="row">
10-
<div class="col-6">
10+
<div class="col-5">
1111
CL: {{ .CLReadyCount }} / {{ .ClientCount }}
1212
</div>
13-
<div class="col-6">
13+
<div class="col-7">
1414
Slot: {{ .CLHeadSlot }}
1515
</div>
1616
</div>
1717
<div class="row">
18-
<div class="col-6">
18+
<div class="col-5">
1919
EL: {{ .ELReadyCount }} / {{ .ClientCount }}
2020
</div>
21-
<div class="col-6">
21+
<div class="col-7">
2222
Block: {{ .ELHeadNumber }}
2323
</div>
2424
</div>

0 commit comments

Comments
 (0)