blob: 5d444677bc320b139bc01940f461846a5be3c4a8 [file]
// Copyright 2022 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 ui
import (
"context"
"math/rand"
"strconv"
"strings"
"time"
"github.com/golang/protobuf/ptypes/empty"
"google.golang.org/grpc"
"chromiumos/tast/errors"
"chromiumos/tast/remote/crosserverutil"
pb "chromiumos/tast/services/cros/ui"
"chromiumos/tast/testing"
"chromiumos/tast/testing/hwdep"
)
const (
defaultUsername = "testuser@gmail.com"
defaultPassword = "testpass"
)
func init() {
testing.AddTest(&testing.Test{
Func: ChromeServiceGRPC,
LacrosStatus: testing.LacrosVariantUnknown,
Desc: "Check basic functionality of ChromeService",
Contacts: []string{"jonfan@google.com", "chromeos-sw-engprod@google.com"},
Attr: []string{"group:mainline", "informational"},
SoftwareDeps: []string{"chrome"},
Vars: []string{"grpcServerPort", "ui.gaiaPoolDefault"},
HardwareDeps: hwdep.D(hwdep.FormFactor(hwdep.Clamshell)),
Params: []testing.Param{{
Name: "default_fake_login",
Val: &pb.NewRequest{},
}, {
Name: "fake_login",
Val: &pb.NewRequest{
LoginMode: pb.LoginMode_LOGIN_MODE_FAKE_LOGIN,
Credentials: &pb.NewRequest_Credentials{
Username: defaultUsername,
Password: defaultPassword,
},
TryReuseSession: false,
KeepState: false,
EnableFeatures: []string{"GwpAsanMalloc", "GwpAsanPartitionAlloc"},
ExtraArgs: []string{"--enable-logging"},
},
}, {
Name: "fake_login_try_reuse_sessions",
Val: &pb.NewRequest{
LoginMode: pb.LoginMode_LOGIN_MODE_FAKE_LOGIN,
Credentials: &pb.NewRequest_Credentials{
Username: defaultUsername,
Password: defaultPassword,
},
TryReuseSession: true,
KeepState: true,
// Requesting the same features and args in order to reuse the same session
EnableFeatures: []string{"GwpAsanMalloc", "GwpAsanPartitionAlloc"},
ExtraArgs: []string{"--enable-logging"},
},
}, {
Name: "gaia_login",
Val: &pb.NewRequest{
// The test definition block has no access to testing.State and "ui.gaiaPoolDefault".
// Credentials will be populated based on "ui.gaiaPoolDefault" in the main test function.
LoginMode: pb.LoginMode_LOGIN_MODE_GAIA_LOGIN,
},
}},
})
}
// ChromeServiceGRPC tests ChromeService functionalities for managing chrome lifecycle.
func ChromeServiceGRPC(ctx context.Context, s *testing.State) {
grpcServerPort := crosserverutil.DefaultGRPCServerPort
if portStr, ok := s.Var("grpcServerPort"); ok {
if portInt, err := strconv.Atoi(portStr); err == nil {
grpcServerPort = portInt
}
}
// Connect to TCP based gRPC Server on DUT.
cl, err := crosserverutil.Dial(ctx, s.DUT(), "localhost", grpcServerPort, true)
if err != nil {
s.Fatal("Failed to connect to the RPC service on the DUT: ", err)
}
defer cl.Close(ctx)
// Populate credentials from Tast variable for the Gaia login test case.
loginReq := s.Param().(*pb.NewRequest)
if loginReq.LoginMode == pb.LoginMode_LOGIN_MODE_GAIA_LOGIN && loginReq.Credentials == nil {
if loginReq.Credentials, err = pickRandomCreds(s.RequiredVar("ui.gaiaPoolDefault")); err != nil {
s.Fatal("Failed to get login credentials: ", err)
}
}
// Start Chrome on DUT
cs := pb.NewChromeServiceClient(cl.Conn)
if _, err := cs.New(ctx, loginReq, grpc.WaitForReady(true)); err != nil {
s.Fatal("Failed to start Chrome: ", err)
}
// Close Chrome on DUT
if _, err := cs.Close(ctx, &empty.Empty{}); err != nil {
s.Fatal("Failed to close Chrome: ", err)
}
}
var random = rand.New(rand.NewSource(time.Now().UnixNano()))
// pickRandomCreds picks a random user and password from a list of credentials.
//
// creds is a string containing multiple credentials separated by newlines:
// user1:pass1
// user2:pass2
// user3:pass3
// ...
func pickRandomCreds(creds string) (*pb.NewRequest_Credentials, error) {
// Pick a random line
lines := strings.Split(creds, "\n")
randomIndex := random.Intn(len(lines))
line := lines[randomIndex]
// Extract user and password from the concatenated string
line = strings.TrimSpace(line)
userNamePassword := strings.SplitN(line, ":", 2)
if len(userNamePassword) != 2 {
return nil, errors.Errorf("failed to parse credential list: line %d: does not contain a colon", randomIndex+1)
}
return &pb.NewRequest_Credentials{
Username: userNamePassword[0],
Password: userNamePassword[1],
}, nil
}