Commit dcb10f54 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

ci: op-heartbeat CI (#4377)

parent ed796b7b
...@@ -959,6 +959,10 @@ workflows: ...@@ -959,6 +959,10 @@ workflows:
binary_name: bss-core binary_name: bss-core
working_directory: bss-core working_directory: bss-core
build: false build: false
- go-lint-test-build:
name: op-heartbeat tests
binary_name: op-heartbeat
working_directory: op-heartbeat
- geth-tests - geth-tests
- integration-tests - integration-tests
- semgrep-scan - semgrep-scan
...@@ -1072,6 +1076,20 @@ workflows: ...@@ -1072,6 +1076,20 @@ workflows:
- gcr - gcr
requires: requires:
- op-proposer-docker-build - op-proposer-docker-build
- docker-build:
name: op-heartbeat-docker-build
docker_file: op-heartbeat/Dockerfile
docker_name: op-heartbeat
docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
docker_context: .
- docker-publish:
name: op-heartbeat-docker-publish
docker_name: op-heartbeat
docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
context:
- gcr
requires:
- op-heartbeat-docker-build
- hive-test: - hive-test:
name: hive-test-rpc name: hive-test-rpc
version: <<pipeline.git.revision>> version: <<pipeline.git.revision>>
......
FROM golang:1.18.0-alpine3.15 as builder
RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash
# build op-heartbeat with local monorepo go modules
COPY ./op-heartbeat/docker.go.work /app/go.work
COPY ./op-heartbeat /app/op-heartbeat
COPY ./op-node /app/op-node
COPY ./op-service /app/op-service
COPY ./.git /app/.git
WORKDIR /app/op-heartbeat
RUN make op-heartbeat
FROM alpine:3.15
COPY --from=builder /app/op-heartbeat/bin/op-heartbeat /usr/local/bin
CMD ["op-heartbeat"]
go 1.18 go 1.18
use ( use (
./op-heartbeat
./op-node ./op-node
./op-service ./op-service
) )
...@@ -10,10 +10,8 @@ import ( ...@@ -10,10 +10,8 @@ import (
const envPrefix = "OP_HEARTBEAT" const envPrefix = "OP_HEARTBEAT"
const ( const (
HTTPAddrFlagName = "http.addr" HTTPAddrFlagName = "http.addr"
HTTPPortFlagName = "http.port" HTTPPortFlagName = "http.port"
HTTPMaxBodySizeFlagName = "http.max-body-size"
AllowedChainIDsFlagName = "allowed-chain-ids"
) )
var ( var (
......
...@@ -79,9 +79,11 @@ func Start(ctx context.Context, l log.Logger, cfg Config, version string) error ...@@ -79,9 +79,11 @@ func Start(ctx context.Context, l log.Logger, cfg Config, version string) error
metrics := NewMetrics(registry) metrics := NewMetrics(registry)
metrics.RecordVersion(version) metrics.RecordVersion(version)
handler := Handler(l, metrics) mux := http.NewServeMux()
mux.HandleFunc("/healthz", HealthzHandler)
mux.Handle("/", Handler(l, metrics))
recorder := opmetrics.NewPromHTTPRecorder(registry, MetricsNamespace) recorder := opmetrics.NewPromHTTPRecorder(registry, MetricsNamespace)
mw := opmetrics.NewHTTPRecordingMiddleware(recorder, handler) mw := opmetrics.NewHTTPRecordingMiddleware(recorder, mux)
server := &http.Server{ server := &http.Server{
Addr: net.JoinHostPort(cfg.HTTPAddr, strconv.Itoa(cfg.HTTPPort)), Addr: net.JoinHostPort(cfg.HTTPAddr, strconv.Itoa(cfg.HTTPPort)),
...@@ -125,3 +127,7 @@ func Handler(l log.Logger, metrics Metrics) http.HandlerFunc { ...@@ -125,3 +127,7 @@ func Handler(l log.Logger, metrics Metrics) http.HandlerFunc {
w.WriteHeader(204) w.WriteHeader(204)
} }
} }
func HealthzHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(204)
}
...@@ -5,24 +5,28 @@ import ( ...@@ -5,24 +5,28 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"net"
"net/http"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-node/heartbeat" "github.com/ethereum-optimism/optimism/op-node/heartbeat"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"io"
"net/http"
"testing"
) )
func TestService(t *testing.T) { func TestService(t *testing.T) {
httpPort := freePort(t)
metricsPort := freePort(t)
cfg := Config{ cfg := Config{
HTTPAddr: "127.0.0.1", HTTPAddr: "127.0.0.1",
HTTPPort: 8080, HTTPPort: httpPort,
HTTPMaxBodySize: 1024 * 1024,
Metrics: opmetrics.CLIConfig{ Metrics: opmetrics.CLIConfig{
Enabled: true, Enabled: true,
ListenAddr: "127.0.0.1", ListenAddr: "127.0.0.1",
ListenPort: 7300, ListenPort: metricsPort,
}, },
} }
...@@ -32,6 +36,14 @@ func TestService(t *testing.T) { ...@@ -32,6 +36,14 @@ func TestService(t *testing.T) {
exitC <- Start(ctx, log.New(), cfg, "foobar") exitC <- Start(ctx, log.New(), cfg, "foobar")
}() }()
// Make sure that the service properly starts
select {
case <-time.NewTimer(100 * time.Millisecond).C:
// pass
case err := <-exitC:
t.Fatalf("unexpected error on startup: %v", err)
}
tests := []struct { tests := []struct {
name string name string
hb heartbeat.Payload hb heartbeat.Payload
...@@ -79,13 +91,15 @@ func TestService(t *testing.T) { ...@@ -79,13 +91,15 @@ func TestService(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
data, err := json.Marshal(tt.hb) data, err := json.Marshal(tt.hb)
require.NoError(t, err) require.NoError(t, err)
req, err := http.NewRequestWithContext(ctx, "POST", "http://127.0.0.1:8080", bytes.NewReader(data)) req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("http://127.0.0.1:%d", httpPort), bytes.NewReader(data))
require.NoError(t, err) require.NoError(t, err)
res, err := http.DefaultClient.Do(req) res, err := http.DefaultClient.Do(req)
require.NoError(t, err) require.NoError(t, err)
defer res.Body.Close()
require.Equal(t, res.StatusCode, 204) require.Equal(t, res.StatusCode, 204)
metricsRes, err := http.Get("http://127.0.0.1:7300") metricsRes, err := http.Get(fmt.Sprintf("http://127.0.0.1:%d", metricsPort))
require.NoError(t, err)
defer metricsRes.Body.Close() defer metricsRes.Body.Close()
require.NoError(t, err) require.NoError(t, err)
metricsBody, err := io.ReadAll(metricsRes.Body) metricsBody, err := io.ReadAll(metricsRes.Body)
...@@ -97,3 +111,12 @@ func TestService(t *testing.T) { ...@@ -97,3 +111,12 @@ func TestService(t *testing.T) {
cancel() cancel()
require.NoError(t, <-exitC) require.NoError(t, <-exitC)
} }
func freePort(t *testing.T) int {
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
require.NoError(t, err)
l, err := net.ListenTCP("tcp", addr)
require.NoError(t, err)
defer l.Close()
return l.Addr().(*net.TCPAddr).Port
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment