From 54a776be223729e7f3dc682f288800f14e171358 Mon Sep 17 00:00:00 2001 From: gfanton <8671905+gfanton@users.noreply.github.com> Date: Sun, 29 Dec 2024 22:10:37 +0100 Subject: [PATCH] fix: make coverage works Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com> --- gno.land/pkg/integration/process.go | 23 +++++-- gno.land/pkg/integration/process/main.go | 61 ++----------------- gno.land/pkg/integration/process_test.go | 4 +- .../pkg/integration/testscript_gnoland.go | 5 ++ 4 files changed, 31 insertions(+), 62 deletions(-) diff --git a/gno.land/pkg/integration/process.go b/gno.land/pkg/integration/process.go index ac7f3247fd6..a7f1186df87 100644 --- a/gno.land/pkg/integration/process.go +++ b/gno.land/pkg/integration/process.go @@ -14,6 +14,7 @@ import ( "os/signal" "slices" "sync" + "testing" "time" "github.com/gnolang/gno/gno.land/pkg/gnoland" @@ -27,6 +28,8 @@ import ( "github.com/stretchr/testify/require" ) +const gracefulShutdown = time.Second * 5 + type ProcessNodeConfig struct { ValidatorKey ed25519.PrivKeyEd25519 `json:"priv"` Verbose bool `json:"verbose"` @@ -40,6 +43,7 @@ type ProcessConfig struct { Node *ProcessNodeConfig // These parameters are not meant to be passed to the process + CoverDir string Stderr, Stdout io.Writer } @@ -187,6 +191,10 @@ func RunNodeProcess(ctx context.Context, cfg ProcessConfig, name string, args .. cmd.Env = os.Environ() cmd.Stdin = bytes.NewReader(nodeConfigData) + if cfg.CoverDir != "" { + cmd.Env = append(cmd.Env, "GOCOVERDIR="+cfg.CoverDir) + } + // Redirect all errors into a buffer cmd.Stderr = os.Stderr if cfg.Stderr != nil { @@ -306,9 +314,8 @@ func RunMain(ctx context.Context, stdin io.Reader, stdout, stderr io.Writer) err // Attempt graceful shutdown select { - case <-ctx.Done(): - err = ctx.Err() - // log.Fatalf("unable to gracefully stop the node, exiting now") + case <-time.After(gracefulShutdown): + return fmt.Errorf("unable to gracefully stop the node, exiting now") case err = <-ccErr: // done } @@ -318,8 +325,16 @@ func RunMain(ctx context.Context, stdin io.Reader, stdout, stderr io.Writer) err func runTestingNodeProcess(t TestingTS, ctx context.Context, pcfg ProcessConfig) NodeProcess { bin, err := os.Executable() require.NoError(t, err) + args := []string{ + "-test.run=^$", + "-run-node-process", + } + + if pcfg.CoverDir != "" && testing.CoverMode() != "" { + args = append(args, "-test.gocoverdir="+pcfg.CoverDir) + } - node, err := RunNodeProcess(ctx, pcfg, bin, "-test.run=^$", "-run-node-process") + node, err := RunNodeProcess(ctx, pcfg, bin, args...) require.NoError(t, err) return node diff --git a/gno.land/pkg/integration/process/main.go b/gno.land/pkg/integration/process/main.go index 57586cdc252..bcd52e6fd44 100644 --- a/gno.land/pkg/integration/process/main.go +++ b/gno.land/pkg/integration/process/main.go @@ -2,68 +2,19 @@ package main import ( "context" - "encoding/json" - "io" - "log" + "fmt" "os" - "os/signal" - "runtime/pprof" "time" "github.com/gnolang/gno/gno.land/pkg/integration" ) -const gracefulShutdown = time.Second * 5 - func main() { - ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) - defer stop() - - // Get the CPU profile path from the environment variable - if profilePath := os.Getenv("CPUPROFILE_PATH"); profilePath != "" { - // Create a file to store the CPU profile - cpuProfile, err := os.Create(profilePath) - if err != nil { - log.Fatalf("could not create CPU profile: %v", err) - } - defer cpuProfile.Close() - - // Start CPU profiling - if err := pprof.StartCPUProfile(cpuProfile); err != nil { - log.Fatalf("could not start CPU profile: %v", err) - } - defer pprof.StopCPUProfile() // Ensure the profile is stopped when the program exits - } - - // Read the configuration from standard input - configData, err := io.ReadAll(os.Stdin) - if err != nil { - log.Fatalf("error reading stdin: %v", err) - } - - // Unmarshal the JSON configuration - var cfg integration.ProcessNodeConfig - if err := json.Unmarshal(configData, &cfg); err != nil { - log.Fatalf("error unmarshaling JSON: %v", err) - } - - // Run the node - ccErr := make(chan error, 1) - go func() { - ccErr <- integration.RunNode(ctx, &cfg, os.Stdout, os.Stderr) - close(ccErr) - }() - - // Wait for the node to gracefully terminate - <-ctx.Done() + ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) + defer cancel() - // Attempt graceful shutdown - select { - case <-time.After(gracefulShutdown): - log.Fatalf("unable to gracefully stop the node, exiting now") - case err := <-ccErr: // done - if err != nil { - log.Fatalf("unable to gracefully stop the node: %v", err) - } + if err := integration.RunMain(ctx, os.Stdin, os.Stdout, os.Stderr); err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + os.Exit(1) } } diff --git a/gno.land/pkg/integration/process_test.go b/gno.land/pkg/integration/process_test.go index 6455732acbb..b8768ad0e63 100644 --- a/gno.land/pkg/integration/process_test.go +++ b/gno.land/pkg/integration/process_test.go @@ -17,8 +17,6 @@ import ( "github.com/stretchr/testify/require" ) -const gracefulShutdown = time.Second * 5 - // Define a flag to indicate whether to run the embedded command var runCommand = flag.Bool("run-node-process", false, "execute the embedded command") @@ -31,7 +29,7 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } - ctx, cancel := context.WithTimeout(context.Background(), gracefulShutdown) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) defer cancel() if err := RunMain(ctx, os.Stdin, os.Stdout, os.Stderr); err != nil { diff --git a/gno.land/pkg/integration/testscript_gnoland.go b/gno.land/pkg/integration/testscript_gnoland.go index 2f7ad539533..423ed0e7bb1 100644 --- a/gno.land/pkg/integration/testscript_gnoland.go +++ b/gno.land/pkg/integration/testscript_gnoland.go @@ -571,6 +571,11 @@ func setupNode(ts *testscript.TestScript, ctx context.Context, cfg *ProcessNodeC Stderr: ts.Stderr(), } + // Setup coverdir provided + if coverdir := ts.Getenv("GOCOVERDIR"); coverdir != "" { + pcfg.CoverDir = coverdir + } + val := ts.Value(envKeyExecCommand) switch cmd := val.(commandkind); cmd {