aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com/google/devtools/build/lib/packages/AttributeContainerTest.java
blob: b9e9c1099c2e4eab7a915da31c93e24385e99c5f (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
136
137
138
139
140
141
142
// Copyright 2015 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 static com.google.common.truth.Truth.assertThat;

import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.events.Location.LineAndColumn;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Unit tests for {@link AttributeContainer}.
 */
@RunWith(JUnit4.class)
public class AttributeContainerTest {

  private RuleClass ruleClass;
  private AttributeContainer container;
  private Attribute attribute1;
  private Attribute attribute2;

  @Before
  public final void createAttributeContainer() throws Exception  {
    ruleClass =
        TestRuleClassProvider.getRuleClassProvider().getRuleClassMap().get("testing_dummy_rule");
    attribute1 = ruleClass.getAttributeByName("srcs");
    attribute2 = ruleClass.getAttributeByName("dummyinteger");
    container = new AttributeContainer(ruleClass);
  }

  @Test
  public void testAttributeSettingAndRetrievalByName() throws Exception {
    Object someValue1 = new Object();
    Object someValue2 = new Object();
    container.setAttributeValueByName(attribute1.getName(), someValue1);
    container.setAttributeValueByName(attribute2.getName(), someValue2);
    assertThat(container.getAttr(attribute1.getName())).isEqualTo(someValue1);
    assertThat(container.getAttr(attribute2.getName())).isEqualTo(someValue2);
    assertThat(container.getAttr("nomatch")).isNull();
  }

  @Test
  public void testExplicitSpecificationsByName() throws Exception {
    // Name-based setters are automatically considered explicit.
    container.setAttributeValueByName(attribute1.getName(), new Object());
    assertThat(container.isAttributeValueExplicitlySpecified(attribute1)).isTrue();
    assertThat(container.isAttributeValueExplicitlySpecified("nomatch")).isFalse();
  }

  @Test
  public void testExplicitSpecificationsByInstance() throws Exception {
    Object someValue = new Object();
    container.setAttributeValue(attribute1, someValue, true);
    container.setAttributeValue(attribute2, someValue, false);
    assertThat(container.isAttributeValueExplicitlySpecified(attribute1)).isTrue();
    assertThat(container.isAttributeValueExplicitlySpecified(attribute2)).isFalse();
  }

  private static Location newLocation() {
    return Location.fromPathAndStartColumn(null, 0, 0, new LineAndColumn(0, 0));
  }

  @Test
  public void testAttributeLocation() throws Exception {
    Location location1 = newLocation();
    Location location2 = newLocation();
    container.setAttributeLocation(attribute1, location1);
    container.setAttributeLocation(attribute2, location2);
    assertThat(container.getAttributeLocation(attribute1.getName())).isEqualTo(location1);
    assertThat(container.getAttributeLocation(attribute2.getName())).isEqualTo(location2);
    assertThat(container.getAttributeLocation("nomatch")).isNull();
  }

  @Test
  public void testPackedState() throws Exception {
    Random rng = new Random();
    // The state packing machinery has special behavior at multiples of 8,
    // so set enough explicit values and locations to exercise that.
    final int N = 17;
    Attribute[] attributes = new Attribute[N];
    for (int i = 0; i < N; ++i) {
      attributes[i] = ruleClass.getAttribute(i);
    }
    Object someValue = new Object();
    Location[] locations = new Location[N];
    for (int i = 0; i < N; ++i) {
      locations[i] = newLocation();
    }
    assertThat(locations[0] != locations[1])
        .isTrue(); // test relies on checking reference inequality
    for (int explicitCount = 0; explicitCount <= N; ++explicitCount) {
      for (int locationCount = 0; locationCount <= N; ++locationCount) {
        AttributeContainer container = new AttributeContainer(ruleClass);
        // Shuffle the attributes each time through, to exercise
        // different stored indices and orderings.
        Collections.shuffle(Arrays.asList(attributes));
        // Also randomly interleave calls to the two setters.
        int valuePassKey = rng.nextInt(1 << N);
        int locationPassKey = rng.nextInt(1 << N);
        for (int pass = 0; pass <= 1; ++pass) {
          for (int i = 0; i < explicitCount; ++i) {
            if (pass == ((valuePassKey >> i) & 1)) {
              container.setAttributeValue(attributes[i], someValue, true);
            }
          }
          for (int i = 0; i < locationCount; ++i) {
            if (pass == ((locationPassKey >> i) & 1)) {
              container.setAttributeLocation(attributes[i], locations[i]);
            }
          }
        }
        for (int i = 0; i < N; ++i) {
          boolean expected = i < explicitCount;
          assertThat(container.isAttributeValueExplicitlySpecified(attributes[i]))
              .isEqualTo(expected);
        }
        for (int i = 0; i < N; ++i) {
          Location expected = i < locationCount ? locations[i] : null;
          assertThat(container.getAttributeLocation(attributes[i].getName())).isSameAs(expected);
        }
      }
    }
  }
}