aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/packages/TestSize.java
blob: 3a7e7caed8bbe7b9a810e8730c707157455d60dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.lib.packages;

import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.common.options.OptionsParsingException;
import java.util.Set;

/**
 * Possible test sizes.
 *
 * Test size may affect the way how test is executed - e.g., it will determine
 * default timeout value and estimated local resource usage.
 */
public enum TestSize {

  // Small tests use small amount of memory, but CPU intensive.
  SMALL(TestTimeout.SHORT, 2),
  // Medium tests tend to use larger amount of memory.
  MEDIUM(TestTimeout.MODERATE, 10),
  // All other tests estimated to use fairly large amount of memory.
  LARGE(TestTimeout.LONG, 20),
  ENORMOUS(TestTimeout.ETERNAL, 30);

  // Memoize canonical lowercase name -> TestSize mappings to avoid extraneous toUpperCases for
  // valueOf.
  private static final ImmutableMap<String, TestSize> CANONICAL_LOWER_CASE_NAME_TABLE;
  static {
    ImmutableMap.Builder<String, TestSize> builder = ImmutableMap.builder();
    for (TestSize size : TestSize.values()) {
      builder.put(size.name().toLowerCase(), size);
    }
    CANONICAL_LOWER_CASE_NAME_TABLE = builder.build();
  }

  private final TestTimeout timeout;
  private final int defaultShards;

  private TestSize(TestTimeout defaultTimeout, int defaultShards) {
    this.timeout = defaultTimeout;
    this.defaultShards = defaultShards;
  }

  /**
   * Returns default timeout in seconds.
   */
  public TestTimeout getDefaultTimeout() {
    return timeout;
  }

  /**
   * Returns default number of shards.
   */
  public int getDefaultShards() { return defaultShards; }

  /**
   * Returns test size of the given test target, or null if the size attribute is unrecognized.
   */
  public static TestSize getTestSize(Rule testTarget) {
    String attr = NonconfigurableAttributeMapper.of(testTarget).get("size", Type.STRING);
    return getTestSize(attr);
  }

  /**
   * Returns {@link TestSize} matching the given timeout or null if the
   * given timeout doesn't match any {@link TestSize}.
   *
   * @param timeout The timeout associated with the desired TestSize.
   */
  public static TestSize getTestSize(TestTimeout timeout) {
    for (TestSize size : TestSize.values()) {
      if (size.timeout == timeout) {
        return size;
      }
    }
    return null;
  }

  /**
   * Normal practice is to always use size tags as lower case strings.
   */
  @Override
  public String toString() {
    return super.toString().toLowerCase();
  }

  /**
   * Returns the enum associated with a test's size or null if the tag is
   * not lower case or an unknown size.
   */
  public static TestSize getTestSize(String attr) {
    if (!attr.equals(attr.toLowerCase())) {
      return null;
    }
    try {
      return CANONICAL_LOWER_CASE_NAME_TABLE.get(attr);
    } catch (IllegalArgumentException e) {
      return null;
    }
  }

  /**
   * Converter for the --test_size_filters option.
   */
  public static class TestSizeFilterConverter extends EnumFilterConverter<TestSize> {
    public TestSizeFilterConverter() {
      super(TestSize.class, "test size");
    }

    /**
     * {@inheritDoc}
     *
     * <p>This override is necessary to prevent OptionsData
     * from throwing a "must be assignable from the converter return type" exception.
     * OptionsData doesn't recognize the generic type and actual type are the same.
     */
    @Override
    public final Set<TestSize> convert(String input) throws OptionsParsingException {
      return super.convert(input);
    }
  }
}