blob: 4a3c930464c3069dd395a33e68c7d511eedee7dc [file] [log] [blame]
// Copyright (C) 2018 The Android Open Source Project
//
// 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.gerrit.server.git;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
import static com.google.gerrit.server.cache.testing.CacheSerializerTestUtil.byteString;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Streams;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.cache.proto.Cache.TagSetHolderProto.TagSetProto;
import com.google.gerrit.server.cache.proto.Cache.TagSetHolderProto.TagSetProto.CachedRefProto;
import com.google.gerrit.server.cache.proto.Cache.TagSetHolderProto.TagSetProto.TagProto;
import com.google.gerrit.server.git.TagSet.CachedRef;
import com.google.gerrit.server.git.TagSet.Tag;
import com.google.inject.TypeLiteral;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdOwnerMap;
import org.junit.Test;
public class TagSetTest {
@Test
public void roundTripToProto() {
HashMap<String, CachedRef> refs = new HashMap<>();
refs.put(
"refs/heads/master",
new CachedRef(1, ObjectId.fromString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")));
refs.put(
"refs/heads/branch",
new CachedRef(2, ObjectId.fromString("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")));
ObjectIdOwnerMap<Tag> tags = new ObjectIdOwnerMap<>();
tags.add(
new Tag(
ObjectId.fromString("cccccccccccccccccccccccccccccccccccccccc"), newBitSet(1, 3, 5)));
tags.add(
new Tag(
ObjectId.fromString("dddddddddddddddddddddddddddddddddddddddd"), newBitSet(2, 4, 6)));
TagSet tagSet = new TagSet(Project.nameKey("project"), refs, tags);
TagSetProto proto = tagSet.toProto();
assertThat(proto)
.ignoringRepeatedFieldOrder()
.isEqualTo(
TagSetProto.newBuilder()
.setProjectName("project")
.putRef(
"refs/heads/master",
CachedRefProto.newBuilder()
.setId(
byteString(
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa))
.setFlag(1)
.build())
.putRef(
"refs/heads/branch",
CachedRefProto.newBuilder()
.setId(
byteString(
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb))
.setFlag(2)
.build())
.addTag(
TagProto.newBuilder()
.setId(
byteString(
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc))
.setFlags(byteString(0x2a))
.build())
.addTag(
TagProto.newBuilder()
.setId(
byteString(
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd))
.setFlags(byteString(0x54))
.build())
.build());
assertEqual(tagSet, TagSet.fromProto(proto));
}
@Test
public void tagSetFields() {
assertThatSerializedClass(TagSet.class)
.hasFields(
ImmutableMap.of(
"projectName", Project.NameKey.class,
"refs", new TypeLiteral<Map<String, CachedRef>>() {}.getType(),
"tags", new TypeLiteral<ObjectIdOwnerMap<Tag>>() {}.getType()));
}
@Test
public void cachedRefFields() {
assertThatSerializedClass(CachedRef.class)
.extendsClass(new TypeLiteral<AtomicReference<ObjectId>>() {}.getType());
assertThatSerializedClass(CachedRef.class)
.hasFields(
ImmutableMap.of(
"flag", int.class, "value", AtomicReference.class.getTypeParameters()[0]));
}
@Test
public void tagFields() {
assertThatSerializedClass(Tag.class).extendsClass(ObjectIdOwnerMap.Entry.class);
assertThatSerializedClass(Tag.class)
.hasFields(
ImmutableMap.<String, Type>builder()
.put("refFlags", BitSet.class)
.put("next", ObjectIdOwnerMap.Entry.class)
.put("w1", int.class)
.put("w2", int.class)
.put("w3", int.class)
.put("w4", int.class)
.put("w5", int.class)
.build());
}
// TODO(dborowitz): Find some more common place to put this method, which requires access to
// package-private TagSet details.
static void assertEqual(@Nullable TagSet a, @Nullable TagSet b) {
if (a == null || b == null) {
assertWithMessage("only one TagSet is null out of\n%s\n%s", a, b)
.that(a == null && b == null)
.isTrue();
return;
}
assertThat(a.getProjectName()).isEqualTo(b.getProjectName());
Map<String, CachedRef> aRefs = a.getRefsForTesting();
Map<String, CachedRef> bRefs = b.getRefsForTesting();
assertWithMessage("ref name set")
.that(ImmutableSortedSet.copyOf(aRefs.keySet()))
.isEqualTo(ImmutableSortedSet.copyOf(bRefs.keySet()));
for (String name : aRefs.keySet()) {
CachedRef aRef = aRefs.get(name);
CachedRef bRef = bRefs.get(name);
assertWithMessage("value of ref %s", name).that(aRef.get()).isEqualTo(bRef.get());
assertWithMessage("flag of ref %s", name).that(aRef.flag).isEqualTo(bRef.flag);
}
ObjectIdOwnerMap<Tag> aTags = a.getTagsForTesting();
ObjectIdOwnerMap<Tag> bTags = b.getTagsForTesting();
assertWithMessage("tag ID set").that(getTagIds(aTags)).isEqualTo(getTagIds(bTags));
for (Tag aTag : aTags) {
Tag bTag = bTags.get(aTag);
assertWithMessage("flags for tag %s", aTag.name())
.that(aTag.refFlags)
.isEqualTo(bTag.refFlags);
}
}
private static ImmutableSortedSet<String> getTagIds(ObjectIdOwnerMap<Tag> bTags) {
return Streams.stream(bTags)
.map(Tag::name)
.collect(ImmutableSortedSet.toImmutableSortedSet(Comparator.naturalOrder()));
}
private BitSet newBitSet(int... bits) {
BitSet result = new BitSet();
Arrays.stream(bits).forEach(result::set);
return result;
}
}