blob: c2e94277ecda865d0fe161026f2fee2da4e95cec [file] [log] [blame] [edit]
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package diag
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"google.golang.org/grpc"
"chromiumos/tast/errors"
"chromiumos/tast/local/chrome"
"chromiumos/tast/local/chrome/uiauto/conndiag"
"chromiumos/tast/services/cros/network"
"chromiumos/tast/testing"
)
func init() {
testing.AddService(&testing.Service{
Register: func(srv *grpc.Server, s *testing.ServiceState) {
network.RegisterNetDiagServiceServer(srv, &NetDiagService{s: s})
},
})
}
// NetDiagService implements tast.cros.network.DiagService
type NetDiagService struct {
s *testing.ServiceState
cr *chrome.Chrome
conn *chrome.Conn
app *conndiag.App
api *MojoAPI
}
// SetupDiagAPI creates a new chrome instance and launches the connectivity
// diagnostics application to be used for running the network diagnostics.
func (d *NetDiagService) SetupDiagAPI(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
if d.api != nil {
return nil, errors.New("Network diagnostics API is already setup")
}
success := false
cr, err := chrome.New(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to start Chrome")
}
defer func() {
if !success {
cr.Close(ctx)
}
}()
app, err := conndiag.Launch(ctx, cr)
if err != nil {
return nil, errors.Wrap(err, "failed to launch connectivity diagnostics app")
}
conn, err := app.ChromeConn(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to get network diagnostics connection")
}
defer func() {
if !success {
conn.Close()
}
}()
api, err := NewMojoAPI(ctx, conn)
if err != nil {
return nil, errors.Wrap(err, "failed to get network diagnostics mojo API")
}
defer func() {
if !success {
api.Release(ctx)
}
}()
success = true
d.cr = cr
d.conn = conn
d.api = api
return &empty.Empty{}, nil
}
// Close will close the connectivity diagnostics application and the
// underlying Chrome instance.
func (d *NetDiagService) Close(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
if err := d.api.Release(ctx); err != nil {
testing.ContextLog(ctx, "Failed to release Network Diagnostics mojo API: ", err)
}
if err := d.conn.Close(); err != nil {
testing.ContextLog(ctx, "Failed to close Chrome connection to app: ", err)
}
if err := d.cr.Close(ctx); err != nil {
testing.ContextLog(ctx, "Failed to close Chrome connection: ", err)
}
return &empty.Empty{}, nil
}
// RunRoutine will run the specified network diagnostic routine and return the
// result.
func (d *NetDiagService) RunRoutine(ctx context.Context, req *network.RunRoutineRequest) (*network.RoutineResult, error) {
if d.api == nil {
return nil, errors.New("Network Diagnostics API has not been setup")
}
res, err := d.api.RunRoutine(ctx, req.Routine)
if err != nil {
return nil, errors.Wrap(err, "failed to run routine")
}
return &network.RoutineResult{Verdict: int32(res.Verdict), Problems: res.Problems}, nil
}