Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into paolo/feat/client
Browse files Browse the repository at this point in the history
  • Loading branch information
otherview committed Sep 13, 2024
2 parents b753aea + 5bc66a8 commit 3191692
Show file tree
Hide file tree
Showing 93 changed files with 1,292 additions and 795 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lint-go.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.59.1
version: v1.60.3
# use the default if on main branch, otherwise use the pull request config
args: --timeout=30m --config=.golangci.yml
only-new-issues: true
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test-e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ jobs:
uses: actions/checkout@v4
with:
repository: vechain/thor-e2e-tests
# https://github.com/vechain/thor-e2e-tests/tree/d86b30b6409b27e841eace0f7c5b6e75c0a4e25e
ref: d86b30b6409b27e841eace0f7c5b6e75c0a4e25e
# https://github.com/vechain/thor-e2e-tests/tree/209f6ea9a81a98dc2d5e42bf036d2878c5837036
ref: 209f6ea9a81a98dc2d5e42bf036d2878c5837036

- name: Download artifact
uses: actions/download-artifact@v4
Expand Down
18 changes: 17 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ linters:
- staticcheck
- bidichk
- durationcheck
- exportloopref
- copyloopvar
- whitespace
- gosec
- revive

# - structcheck # lots of false positives
# - errcheck #lot of false positives
Expand All @@ -38,6 +39,21 @@ linters:
linters-settings:
gofmt:
simplify: true
gosec:
excludes:
- G115
- G406 # ignore ripe160 deprecation
- G507 # ignore ripe160 deprecation
revive:
rules:
- name: var-naming
severity: warning
disabled: false
exclude: [""]
arguments:
- [] # AllowList
- [] # DenyList
- - upperCaseConst: true # Extra parameter (upperCaseConst|skipPackageNameChecks)

issues:
max-issues-per-linter: 1000
Expand Down
103 changes: 0 additions & 103 deletions admin/admin.go

This file was deleted.

4 changes: 2 additions & 2 deletions api/accounts/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ type Accounts struct {
stater *state.Stater
callGasLimit uint64
forkConfig thor.ForkConfig
bft bft.Finalizer
bft bft.Committer
}

func New(
repo *chain.Repository,
stater *state.Stater,
callGasLimit uint64,
forkConfig thor.ForkConfig,
bft bft.Finalizer,
bft bft.Committer,
) *Accounts {
return &Accounts{
repo,
Expand Down
62 changes: 62 additions & 0 deletions api/admin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) 2024 The VeChainThor developers

// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying
// file LICENSE or <https://www.gnu.org/licenses/lgpl-3.0.html>

package api

import (
"log/slog"
"net/http"

"github.com/pkg/errors"
"github.com/vechain/thor/v2/api/utils"
"github.com/vechain/thor/v2/log"
)

type logLevelRequest struct {
Level string `json:"level"`
}

type logLevelResponse struct {
CurrentLevel string `json:"currentLevel"`
}

func getLogLevelHandler(logLevel *slog.LevelVar) utils.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) error {
return utils.WriteJSON(w, logLevelResponse{
CurrentLevel: logLevel.Level().String(),
})
}
}

func postLogLevelHandler(logLevel *slog.LevelVar) utils.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) error {
var req logLevelRequest

if err := utils.ParseJSON(r.Body, &req); err != nil {
return utils.BadRequest(errors.WithMessage(err, "Invalid request body"))
}

switch req.Level {
case "debug":
logLevel.Set(log.LevelDebug)
case "info":
logLevel.Set(log.LevelInfo)
case "warn":
logLevel.Set(log.LevelWarn)
case "error":
logLevel.Set(log.LevelError)
case "trace":
logLevel.Set(log.LevelTrace)
case "crit":
logLevel.Set(log.LevelCrit)
default:
return utils.BadRequest(errors.New("Invalid verbosity level"))
}

return utils.WriteJSON(w, logLevelResponse{
CurrentLevel: logLevel.Level().String(),
})
}
}
56 changes: 56 additions & 0 deletions api/admin_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (c) 2024 The VeChainThor developers

// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying
// file LICENSE or <https://www.gnu.org/licenses/lgpl-3.0.html>

package api

import (
"log/slog"
"net"
"net/http"
"time"

"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"github.com/pkg/errors"
"github.com/vechain/thor/v2/api/utils"
"github.com/vechain/thor/v2/co"
)

func HTTPHandler(logLevel *slog.LevelVar) http.Handler {
router := mux.NewRouter()
sub := router.PathPrefix("/admin").Subrouter()
sub.Path("/loglevel").
Methods(http.MethodGet).
Name("get-log-level").
HandlerFunc(utils.WrapHandlerFunc(getLogLevelHandler(logLevel)))

sub.Path("/loglevel").
Methods(http.MethodPost).
Name("post-log-level").
HandlerFunc(utils.WrapHandlerFunc(postLogLevelHandler(logLevel)))

return handlers.CompressHandler(router)
}

func StartAdminServer(addr string, logLevel *slog.LevelVar) (string, func(), error) {
listener, err := net.Listen("tcp", addr)
if err != nil {
return "", nil, errors.Wrapf(err, "listen admin API addr [%v]", addr)
}

router := mux.NewRouter()
router.PathPrefix("/admin").Handler(HTTPHandler(logLevel))
handler := handlers.CompressHandler(router)

srv := &http.Server{Handler: handler, ReadHeaderTimeout: time.Second, ReadTimeout: 5 * time.Second}
var goes co.Goes
goes.Go(func() {
srv.Serve(listener)
})
return "http://" + listener.Addr().String() + "/admin", func() {
srv.Close()
goes.Wait()
}, nil
}
99 changes: 99 additions & 0 deletions api/admin_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright (c) 2024 The VeChainThor developers

// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying
// file LICENSE or <https://www.gnu.org/licenses/lgpl-3.0.html>

package api

import (
"bytes"
"encoding/json"
"log/slog"
"net/http"
"net/http/httptest"
"strings"
"testing"

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

type TestCase struct {
name string
method string
body interface{}
expectedStatus int
expectedLevel string
expectedErrorMsg string
}

func marshalBody(tt TestCase, t *testing.T) []byte {
var reqBody []byte
var err error
if tt.body != nil {
reqBody, err = json.Marshal(tt.body)
if err != nil {
t.Fatalf("could not marshal request body: %v", err)
}
}
return reqBody
}

func TestLogLevelHandler(t *testing.T) {
tests := []TestCase{
{
name: "Valid POST input - set level to DEBUG",
method: "POST",
body: map[string]string{"level": "debug"},
expectedStatus: http.StatusOK,
expectedLevel: "DEBUG",
},
{
name: "Invalid POST input - invalid level",
method: "POST",
body: map[string]string{"level": "invalid_body"},
expectedStatus: http.StatusBadRequest,
expectedErrorMsg: "Invalid verbosity level",
},
{
name: "GET request - get current level INFO",
method: "GET",
body: nil,
expectedStatus: http.StatusOK,
expectedLevel: "INFO",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var logLevel slog.LevelVar
logLevel.Set(slog.LevelInfo)

reqBodyBytes := marshalBody(tt, t)

req, err := http.NewRequest(tt.method, "/admin/loglevel", bytes.NewBuffer(reqBodyBytes))
if err != nil {
t.Fatal(err)
}

rr := httptest.NewRecorder()
handler := http.HandlerFunc(HTTPHandler(&logLevel).ServeHTTP)
handler.ServeHTTP(rr, req)

if status := rr.Code; status != tt.expectedStatus {
t.Errorf("handler returned wrong status code: got %v want %v", status, tt.expectedStatus)
}

if tt.expectedLevel != "" {
var response logLevelResponse
if err := json.NewDecoder(rr.Body).Decode(&response); err != nil {
t.Fatalf("could not decode response: %v", err)
}
if response.CurrentLevel != tt.expectedLevel {
t.Errorf("handler returned unexpected log level: got %v want %v", response.CurrentLevel, tt.expectedLevel)
}
} else {
assert.Equal(t, tt.expectedErrorMsg, strings.Trim(rr.Body.String(), "\n"))
}
})
}
}
Loading

0 comments on commit 3191692

Please sign in to comment.