/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you maynot 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 applicablelaw 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 org.apache.phoenix.end2end;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.apache.phoenix.query.BaseTest;

/**
 * 
 * Annotation to denote that the test lets HBase manage timestamp 
 * itself. Tests in these category do not drop HBase tables at 
 * the end of every test class. To prevent table name collisions that could happen otherwise,
 * these tests use random table names generated by {@link BaseTest#generateRandomString}.
 * 
 * Tests using a mini cluster need to be classified either 
 * as {@link ParallelStatsDisabledTest} or {@link ClientManagedTimeTest}
 * or {@link NeedsOwnMiniClusterTest} or {@link HBaseManagedTimeTest} otherwise they won't be run
 * when one runs mvn verify or mvn install.
 * 
 * @since 4.1
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ParallelStatsDisabledTest {

}
