diff --git a/cmd/faultdetector/main_test.go b/cmd/faultdetector/main_test.go index 30406f6..d454d94 100644 --- a/cmd/faultdetector/main_test.go +++ b/cmd/faultdetector/main_test.go @@ -12,16 +12,19 @@ import ( "github.com/LiskHQ/op-fault-detector/pkg/api" v1 "github.com/LiskHQ/op-fault-detector/pkg/api/handlers/v1" + "github.com/LiskHQ/op-fault-detector/pkg/chain" "github.com/LiskHQ/op-fault-detector/pkg/config" "github.com/LiskHQ/op-fault-detector/pkg/faultdetector" "github.com/LiskHQ/op-fault-detector/pkg/log" "github.com/LiskHQ/op-fault-detector/pkg/utils/notification" + "github.com/ethereum/go-ethereum/core/types" "github.com/gin-gonic/gin" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" promClient "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" ) const ( @@ -29,14 +32,25 @@ const ( port = 8080 ) -// type mockChainAPIClient struct { -// mock.Mock -// } +type mockChainAPIClient struct { + mock.Mock +} + +func (m *mockChainAPIClient) GetBlockHeaderByNumber(ctx context.Context) (*types.Header, error) { + called := m.MethodCalled("GetBlockHeaderByNumber", ctx) + return called.Get(0).(*types.Header), called.Error(1) +} + +func (c *mockChainAPIClient) BlockNumber(ctx context.Context) (uint64, error) { + ret := c.Called(ctx) + + return ret.Get(0).(uint64), ret.Error(1) +} -// func (m *mockChainAPIClient) GetLatestBlockHeader(ctx context.Context) (*types.Header, error) { -// called := m.MethodCalled("GetLatestBlockHeader", ctx) -// return called.Get(0).(*types.Header), called.Error(1) -// } +func (m *mockChainAPIClient) GetProof(ctx context.Context) (*chain.ProofResponse, error) { + called := m.MethodCalled("GetProof", ctx) + return called.Get(0).(*chain.ProofResponse), called.Error(1) +} func prepareHTTPServer(t *testing.T, ctx context.Context, logger log.Logger, wg *sync.WaitGroup, erroChan chan error) *api.HTTPServer { router := gin.Default() @@ -59,27 +73,26 @@ func prepareFaultDetector(t *testing.T, ctx context.Context, logger log.Logger, if valid { fd, _ = faultdetector.NewFaultDetector(ctx, logger, erroChan, wg, config.FaultDetectorConfig, reg, ¬ification.Notification{}) } else { - // TODO: Mock chains API - // l1RpcApi, _ := chain.GetAPIClient(ctx, "https://rpc.notadegen.com/eth", logger) - // var l2RpcApi = new(mockChainAPIClient) - - // fd = &faultdetector.FaultDetector{ - // Ctx: ctx, - // Logger: logger, - // ErrorChan: erroChan, - // Wg: wg, - // Metrics: &faultdetector.FaultDetectorMetrics{}, - // L1RpcApi: l1RpcApi, - // L2RpcApi: l2RpcApi, - // OracleContractAccessor: &chain.OracleAccessor{}, - // FaultProofWindow: 60480, - // CurrentOutputIndex: 1, - // Diverged: false, - // Ticker: time.NewTicker(2 * time.Second), - // QuitTickerChan: make(chan struct{}), - // Notification: ¬ification.Notification{}, - // } - fd = &faultdetector.FaultDetector{} + // TODO: Mock chains APIs + l1RpcApi, _ := chain.GetAPIClient(ctx, "https://rpc.notadegen.com/eth", logger) + l2RpcApi := new(mockChainAPIClient) + + fd = &faultdetector.FaultDetector{ + Ctx: ctx, + Logger: logger, + ErrorChan: erroChan, + Wg: wg, + Metrics: &faultdetector.FaultDetectorMetrics{}, + L1RpcApi: l1RpcApi, + L2RpcApi: l2RpcApi, + OracleContractAccessor: &chain.OracleAccessor{}, + FaultProofWindow: 60480, + CurrentOutputIndex: 1, + Diverged: false, + Ticker: time.NewTicker(2 * time.Second), + QuitTickerChan: make(chan struct{}), + Notification: ¬ification.Notification{}, + } } return fd @@ -136,7 +149,7 @@ func parseMetricRes(input *strings.Reader) []map[string]map[string]interface{} { return parsedOutput } -func TestApp_Start(t *testing.T) { +func TestMain_E2E(t *testing.T) { gin.SetMode(gin.TestMode) ctx := context.Background() @@ -148,6 +161,7 @@ func TestApp_Start(t *testing.T) { testConfig := prepareConfig(&testing.T{}) testServer := prepareHTTPServer(&testing.T{}, ctx, logger, &wg, erroChan) testFaultDetector := prepareFaultDetector(&testing.T{}, ctx, logger, registry, testConfig, &wg, erroChan, true) + testFaultDetectorMocked := prepareFaultDetector(&testing.T{}, ctx, logger, registry, testConfig, &wg, erroChan, false) // Register handler testServer.Router.GET("/status", v1.GetStatus) @@ -158,7 +172,7 @@ func TestApp_Start(t *testing.T) { App App }{ { - name: "should start application without any issue", + name: "should start application with no faults detected", App: App{ ctx: ctx, logger: logger, @@ -170,6 +184,19 @@ func TestApp_Start(t *testing.T) { wg: &wg, }, }, + { + name: "should start application with fault detected", + App: App{ + ctx: ctx, + logger: logger, + errChan: erroChan, + config: testConfig, + apiServer: testServer, + faultDetector: testFaultDetectorMocked, + notification: ¬ification.Notification{}, + wg: &wg, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -199,8 +226,7 @@ func TestApp_Start(t *testing.T) { assert.NoError(t, err) body, err := io.ReadAll(res.Body) assert.NoError(t, err) - stringBody := string(body) - parsedMetric := parseMetricRes(strings.NewReader(stringBody)) + parsedMetric := parseMetricRes(strings.NewReader(string(body))) for _, m := range parsedMetric { if m["fault_detector_is_state_mismatch"] != nil { expectedOutput := float64(0) @@ -213,7 +239,6 @@ func TestApp_Start(t *testing.T) { }) wg.Add(1) - go func() { app.Start() }() diff --git a/go.mod b/go.mod index b77416b..a7a9eb4 100644 --- a/go.mod +++ b/go.mod @@ -73,8 +73,8 @@ require ( github.com/pelletier/go-toml/v2 v2.1.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/client_model v0.5.0 + github.com/prometheus/common v0.45.0 github.com/prometheus/procfs v0.12.0 // indirect github.com/rivo/uniseg v0.4.3 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect