blob: 1a183a0ddf41d91405e4aa246793443f7d473985 [file] [log] [blame]
// Copyright 2018 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 testexec
import (
"fmt"
"sort"
)
// Shards is a JSON representation of a set of shards, used for serialization.
type Shards struct {
// Shards is a list of test shards.
Shards []*Shard `json:"shards"`
}
// Shard represents a set of tests with a common execution environment.
type Shard struct {
// Name is the identifier for the shard.
Name string `json:"name"`
// Tests is the set of test to be executed in this shard.
Tests []Test `json:"tests"`
// Env is a generalized notion of the execution environment for the shard.
Env Environment `json:"environment"`
}
// MakeShards is the core algorithm to this tool. It takes a set of test specs and produces
// a set of shards which may then be converted into Swarming tasks.
//
// This is the most naive algorithm at the moment. It just merges all tests together which
// have the same environment setting into the same shard.
func MakeShards(specs []TestSpec, prefix string) []*Shard {
// Collect the order of the shards so our shard ordering is deterministic with
// respect to the input.
envToSuites := make(map[Environment][]Test)
envs := []Environment{}
for _, spec := range specs {
for _, env := range spec.Envs {
if _, ok := envToSuites[env]; !ok {
envs = append(envs, env)
}
envToSuites[env] = append(envToSuites[env], spec.Test)
}
}
shards := make([]*Shard, 0, len(envs))
for i, env := range envs {
tests := envToSuites[env]
sort.Slice(tests, func(i, j int) bool {
return tests[i].Location < tests[j].Location
})
name := fmt.Sprintf("%04d", i)
if prefix != "" {
name = fmt.Sprintf("%s-%s", prefix, name)
}
shards = append(shards, &Shard{
Name: name,
Tests: tests,
Env: env,
})
}
return shards
}