From 30262487887b16836519955e0c8f2f0544fd7fa9 Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Fri, 3 Jan 2025 19:05:41 +0000 Subject: [PATCH] all: Add hive instance information endpoint --- hive.go | 8 ++++++-- hivesim/hive_test.go | 5 ++++- internal/libhive/api.go | 12 ++++++++++-- internal/libhive/inventory.go | 8 ++++---- internal/libhive/run.go | 12 ++++++------ internal/libhive/run_test.go | 2 +- internal/libhive/testmanager.go | 17 +++++++++++++++-- 7 files changed, 46 insertions(+), 18 deletions(-) diff --git a/hive.go b/hive.go index a423f7b862..8d56cbaec3 100644 --- a/hive.go +++ b/hive.go @@ -168,20 +168,24 @@ func main() { clientList = libhive.FilterClients(clientList, filter) } } + hiveInfo := libhive.HiveInfo{ + Command: os.Args, + ClientFile: clientList, + } // Build clients and simulators. if err := runner.Build(ctx, clientList, simList, simBuildArgs); err != nil { fatal(err) } if *simDevMode { - runner.RunDevMode(ctx, env, *simDevModeAPIEndpoint) + runner.RunDevMode(ctx, env, *simDevModeAPIEndpoint, hiveInfo) return } // Run simulators. var failCount int for _, sim := range simList { - result, err := runner.Run(ctx, sim, env) + result, err := runner.Run(ctx, sim, env, hiveInfo) if err != nil { fatal(err) } diff --git a/hivesim/hive_test.go b/hivesim/hive_test.go index 0a76b6f491..c959ee395e 100644 --- a/hivesim/hive_test.go +++ b/hivesim/hive_test.go @@ -407,7 +407,10 @@ func newFakeAPI(hooks *fakes.BackendHooks) (*libhive.TestManager, *httptest.Serv } env := libhive.SimEnv{} backend := fakes.NewContainerBackend(hooks) - tm := libhive.NewTestManager(env, backend, defs) + hiveInfo := libhive.HiveInfo{ + Command: []string{"/hive"}, + } + tm := libhive.NewTestManager(env, backend, defs, hiveInfo) srv := httptest.NewServer(tm.API()) return tm, srv } diff --git a/internal/libhive/api.go b/internal/libhive/api.go index 3bbbbbf647..62fecbb00e 100644 --- a/internal/libhive/api.go +++ b/internal/libhive/api.go @@ -27,11 +27,12 @@ const hiveEnvvarPrefix = "HIVE_" const defaultStartTimeout = time.Duration(60 * time.Second) // newSimulationAPI creates handlers for the simulation API. -func newSimulationAPI(b ContainerBackend, env SimEnv, tm *TestManager) http.Handler { - api := &simAPI{backend: b, env: env, tm: tm} +func newSimulationAPI(b ContainerBackend, env SimEnv, tm *TestManager, hive HiveInfo) http.Handler { + api := &simAPI{backend: b, env: env, tm: tm, hive: hive} // API routes. router := mux.NewRouter() + router.HandleFunc("/hive", api.getHiveInfo).Methods("GET") router.HandleFunc("/clients", api.getClientTypes).Methods("GET") router.HandleFunc("/testsuite/{suite}/test/{test}/node/{node}/exec", api.execInClient).Methods("POST") router.HandleFunc("/testsuite/{suite}/test/{test}/node/{node}", api.getNodeStatus).Methods("GET") @@ -56,6 +57,13 @@ type simAPI struct { backend ContainerBackend env SimEnv tm *TestManager + hive HiveInfo +} + +// getHiveInfo returns information about the hive server instance. +func (api *simAPI) getHiveInfo(w http.ResponseWriter, r *http.Request) { + slog.Info("API: hive info requested") + serveJSON(w, api.hive) } // getClientTypes returns all known client types. diff --git a/internal/libhive/inventory.go b/internal/libhive/inventory.go index 42302dfa79..3376d665a8 100644 --- a/internal/libhive/inventory.go +++ b/internal/libhive/inventory.go @@ -183,19 +183,19 @@ func loadClientMetadata(path string) (m ClientMetadata, err error) { type ClientDesignator struct { // Client is the client name. // This must refer to a subdirectory of clients/ - Client string `yaml:"client"` + Client string `yaml:"client" json:"client"` // Nametag is used in the name of the client image. // This is for assigning meaningful names to different builds of the same client. // If unspecified, a default value is chosen to make client names unique. - Nametag string `yaml:"nametag,omitempty"` + Nametag string `yaml:"nametag,omitempty" json:"nametag,omitempty"` // DockerfileExt is the extension of the Docker that should be used to build the // client. Example: setting this to "git" will build using "Dockerfile.git". - DockerfileExt string `yaml:"dockerfile,omitempty"` + DockerfileExt string `yaml:"dockerfile,omitempty" json:"dockerfile,omitempty"` // Arguments passed to the docker build. - BuildArgs map[string]string `yaml:"build_args,omitempty"` + BuildArgs map[string]string `yaml:"build_args,omitempty" json:"build_args,omitempty"` } func (c ClientDesignator) buildString() string { diff --git a/internal/libhive/run.go b/internal/libhive/run.go index 7e4270d863..daa6b6099d 100644 --- a/internal/libhive/run.go +++ b/internal/libhive/run.go @@ -99,12 +99,12 @@ func (r *Runner) buildSimulators(ctx context.Context, simList []string, buildArg return nil } -func (r *Runner) Run(ctx context.Context, sim string, env SimEnv) (SimResult, error) { +func (r *Runner) Run(ctx context.Context, sim string, env SimEnv, hiveInfo HiveInfo) (SimResult, error) { if err := createWorkspace(env.LogDir); err != nil { return SimResult{}, err } writeInstanceInfo(env.LogDir) - return r.run(ctx, sim, env) + return r.run(ctx, sim, env, hiveInfo) } // RunDevMode starts simulator development mode. In this mode, the simulator is not @@ -112,7 +112,7 @@ func (r *Runner) Run(ctx context.Context, sim string, env SimEnv) (SimResult, er // on the docker network. // // Note: Sim* options in env are ignored, but Client* options and LogDir still apply. -func (r *Runner) RunDevMode(ctx context.Context, env SimEnv, endpoint string) error { +func (r *Runner) RunDevMode(ctx context.Context, env SimEnv, endpoint string, hiveInfo HiveInfo) error { if err := createWorkspace(env.LogDir); err != nil { return err } @@ -120,7 +120,7 @@ func (r *Runner) RunDevMode(ctx context.Context, env SimEnv, endpoint string) er for _, def := range r.clientDefs { clientDefs = append(clientDefs, def) } - tm := NewTestManager(env, r.container, clientDefs) + tm := NewTestManager(env, r.container, clientDefs, hiveInfo) defer func() { if err := tm.Terminate(); err != nil { slog.Error("could not terminate test manager", "error", err) @@ -158,7 +158,7 @@ HIVE_SIMULATOR=http://%v } // run runs one simulation. -func (r *Runner) run(ctx context.Context, sim string, env SimEnv) (SimResult, error) { +func (r *Runner) run(ctx context.Context, sim string, env SimEnv, hiveInfo HiveInfo) (SimResult, error) { slog.Info(fmt.Sprintf("running simulation: %s", sim)) clientDefs := make([]*ClientDefinition, 0) @@ -182,7 +182,7 @@ func (r *Runner) run(ctx context.Context, sim string, env SimEnv) (SimResult, er } // Start the simulation API. - tm := NewTestManager(env, r.container, clientDefs) + tm := NewTestManager(env, r.container, clientDefs, hiveInfo) defer func() { if err := tm.Terminate(); err != nil { slog.Error("could not terminate test manager", "error", err) diff --git a/internal/libhive/run_test.go b/internal/libhive/run_test.go index 31899cb5ea..374ae5fd66 100644 --- a/internal/libhive/run_test.go +++ b/internal/libhive/run_test.go @@ -52,7 +52,7 @@ func TestRunner(t *testing.T) { if err := runner.Build(ctx, allClients, simList, buildArgs); err != nil { t.Fatal("Build() failed:", err) } - if _, err := runner.Run(context.Background(), "sim-1", simOpt); err != nil { + if _, err := runner.Run(context.Background(), "sim-1", simOpt, libhive.HiveInfo{}); err != nil { t.Fatal("Run() failed:", err) } diff --git a/internal/libhive/testmanager.go b/internal/libhive/testmanager.go index 4f54052d64..347f29058f 100644 --- a/internal/libhive/testmanager.go +++ b/internal/libhive/testmanager.go @@ -58,11 +58,20 @@ type SimResult struct { TestsFailed int } +// HiveInfo contains information about the hive instance running the simulation. +type HiveInfo struct { + Command []string `json:"command"` + ClientFile []ClientDesignator `json:"clientFile"` + Commit string `json:"commit"` + Date string `json:"date"` +} + // TestManager collects test results during a simulation run. type TestManager struct { config SimEnv backend ContainerBackend clientDefs []*ClientDefinition + hiveInfo HiveInfo simContainerID string simLogFile string @@ -81,11 +90,15 @@ type TestManager struct { results map[TestSuiteID]*TestSuite } -func NewTestManager(config SimEnv, b ContainerBackend, clients []*ClientDefinition) *TestManager { +func NewTestManager(config SimEnv, b ContainerBackend, clients []*ClientDefinition, hiveInfo HiveInfo) *TestManager { + if hiveInfo.Commit == "" && hiveInfo.Date == "" { + hiveInfo.Commit, hiveInfo.Date = hiveVersion() + } return &TestManager{ clientDefs: clients, config: config, backend: b, + hiveInfo: hiveInfo, runningTestSuites: make(map[TestSuiteID]*TestSuite), runningTestCases: make(map[TestID]*TestCase), results: make(map[TestSuiteID]*TestSuite), @@ -115,7 +128,7 @@ func (manager *TestManager) Results() map[TestSuiteID]*TestSuite { // API returns the simulation API handler. func (manager *TestManager) API() http.Handler { - return newSimulationAPI(manager.backend, manager.config, manager) + return newSimulationAPI(manager.backend, manager.config, manager, manager.hiveInfo) } // IsTestSuiteRunning checks if the test suite is still running and returns it if so