blob: 81527455444bad99496da5f351245a6aa8a6e086 [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Provides service implementations and management
package services
import (
"context"
"fmt"
"golang.org/x/exp/maps"
buildapi "go.chromium.org/chromiumos/config/go/build/api"
"go.chromium.org/chromiumos/config/go/test/api"
)
// LocalCFTManager acts as the middle man between the CLI args
// and the concrete management of the services being run.
// Handles knowledge of which services are running, as well as
// how to start, stop, and pass commands to services.
type LocalCFTManager struct {
services map[string]Service
servicesStarted []string
servicesResults map[string]ServiceResult_
ports map[string]uint16
ctx context.Context
Board string
Model string
Build string
Tests []string
Tags []string
TagsExclude []string
DutHost string
BaseDir string
Chroot string
LocalServices map[string]struct{}
imagePath string
images map[string]*buildapi.ContainerImageInfo
testSuites []*api.TestSuite
testResponse *api.CrosTestResponse
err error
}
type services struct {
CrosToolRunner string
CrosProvision string
CrosDut string
CrosTest string
CrosTestFinder string
CacheServer string
SSHTunnel string
SSHReverseTunnel string
}
// Enum of defined runnable services
func SERVICES() services {
return services{
CrosToolRunner: "cros-tool-runner",
CrosProvision: "cros-provision",
CrosDut: "cros-dut",
CrosTest: "cros-test",
CrosTestFinder: "cros-test-finder",
CacheServer: "cache-server",
SSHTunnel: "ssh-tunnel",
SSHReverseTunnel: "ssh-reverse-tunnel",
}
}
// Initializes a LocalCFTManager
func NewLocalCFTManager(
ctx context.Context,
board, model, build, dutHost, baseDir, chroot string,
tests, tags, tagsExclude, localServices []string,
ports map[string]uint16,
) *LocalCFTManager {
localServicesMap := map[string]struct{}{}
for _, service := range localServices {
localServicesMap[service] = struct{}{}
}
return &LocalCFTManager{
ctx: ctx,
services: make(map[string]Service),
servicesStarted: []string{},
servicesResults: map[string]string{},
ports: maps.Clone(ports),
images: make(map[string]*buildapi.ContainerImageInfo),
Board: board,
Model: model,
Build: build,
DutHost: dutHost,
BaseDir: baseDir,
Chroot: chroot,
Tests: tests,
Tags: tags,
TagsExclude: tagsExclude,
imagePath: "",
LocalServices: localServicesMap,
err: nil,
}
}
// Calls the service to start then logs the service as running
func (c *LocalCFTManager) Start(serviceName string, service Service) error {
c.services[serviceName] = service
c.servicesResults[serviceName] = SERVICE_RESULT().Undefined
c.servicesStarted = append([]string{serviceName}, c.servicesStarted...)
err := c.services[serviceName].Start()
if err != nil {
c.servicesResults[serviceName] = SERVICE_RESULT().Failed
} else {
c.servicesResults[serviceName] = SERVICE_RESULT().Success
}
c.err = err
return err
}
// Passes the command to the specified service
func (c *LocalCFTManager) Execute(serviceName, commandName ServiceCommand_, args ...interface{}) error {
c.servicesResults[serviceName] = SERVICE_RESULT().Undefined
err := c.services[serviceName].Execute(commandName, args)
if err != nil {
c.servicesResults[serviceName] = SERVICE_RESULT().Failed
} else {
c.servicesResults[serviceName] = SERVICE_RESULT().Success
}
c.err = err
return err
}
// Stops all services that are running in the reverse order of when they started
func (c *LocalCFTManager) Stop() (err error) {
for _, service := range c.servicesStarted {
fmt.Printf("Stopping %s\n", service)
if innerErr := c.services[service].Stop(); innerErr != nil {
err = fmt.Errorf("%s, %s", innerErr, err)
}
delete(c.services, service)
}
c.servicesStarted = []string{}
return
}
// PrintResults list out the statuses of the services that ran during execution
func (c *LocalCFTManager) PrintResults() {
overall := SERVICE_RESULT().Success
for service, status := range c.servicesResults {
fmt.Printf("%s: %s\n", service, status)
if status == SERVICE_RESULT().Failed || status == SERVICE_RESULT().Undefined {
overall = status
}
}
fmt.Printf("\nOverall Verdict: %s\n", overall)
if c.err != nil {
fmt.Printf("local-cft failed: %s\n", c.err)
}
}