blob: ec5b9e048461678656607f5c517d2f73dfcd0c6a [file] [log] [blame]
// Copyright 2022 The Fuchsia 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 testrunner
import (
"context"
"fmt"
"net"
"strings"
"time"
"go.fuchsia.dev/fuchsia/tools/integration/testsharder"
"go.fuchsia.dev/fuchsia/tools/lib/osmisc"
"go.fuchsia.dev/fuchsia/tools/lib/retry"
"go.fuchsia.dev/fuchsia/tools/net/sshutil"
)
// ResolveTestPackages resolves all test packages serially used by the given slice of tests.
func ResolveTestPackages(ctx context.Context, tests []testsharder.Test, addr net.IPAddr, sshKeyFile, resolveLog string) error {
client, err := sshToTarget(ctx, addr, sshKeyFile, "resolve")
if err != nil {
return fmt.Errorf("failed to establish an SSH connection: %w", err)
}
defer client.Close()
l, err := osmisc.CreateFile(resolveLog)
if err != nil {
return fmt.Errorf("failed to create log for package resolutions: %w", err)
}
defer l.Close()
urls := make(map[string]struct{})
var orderedURLs []string
for _, test := range tests {
// Removes the resource path from the package URL, as pkgctl does not
// support resource paths.
pkgURL := strings.Split(test.PackageURL, "#")[0]
if _, exists := urls[pkgURL]; !exists {
urls[pkgURL] = struct{}{}
orderedURLs = append(orderedURLs, pkgURL)
}
}
// Resolve each of the packages serially.
// Note that this package resolution is best effort, as run-test-suite
// invocations will force a resolution even if this fails.
for _, url := range orderedURLs {
select {
case <-ctx.Done():
return nil
case <-time.After(2 * time.Second):
cmd := []string{"pkgctl", "resolve", url}
backoff := retry.NewConstantBackoff(1 * time.Second)
const maxReconnectAttempts = 3
retry.Retry(ctx, retry.WithMaxAttempts(backoff, maxReconnectAttempts), func() error {
if err := client.Run(ctx, cmd, l, l); err != nil {
if !sshutil.IsConnectionError(err) {
return retry.Fatal(err)
}
if err := client.Reconnect(ctx); err != nil {
return retry.Fatal(err)
}
return err
}
return nil
}, nil)
}
}
return nil
}