# 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 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.
# Welcome to Bigtop!

Bigtop (http://bigtop.apache.org/) is a project for the development of
packaging and tests of the Apache Hadoop (http://hadoop.apache.org/)
ecosystem.

The primary goal of Bigtop is to build a community around the
packaging and interoperability testing of Hadoop-related
projects. This includes testing at various levels (packaging,
platform, runtime, upgrade, etc...) developed by a community with a
focus on the system as a whole, rather than individual projects.

## Building Bigtop

Packages have been built for CentOS/RHEL 5 and 6, Fedora 17,
SuSE Linux Enterprise 11, OpenSUSE12.2, Ubuntu LTS Lucid and Precise,
and Ubuntu Quantal. They can probably be built for other platforms as
well.Some of the binary artifacts might be compatible with other closely
related distributions.

Building Bigtop requires the following tools:

* Java JDK 1.6
* Apache Forrest 0.8 (requires 32bit version of Java JDK 1.5)
* Apache Ant
* Apache Maven
* git
* subversion
* autoconf
* automake
* liblzo2-dev
* libz-dev
* sharutils
* libfuse-dev
* libssl-dev 

On Debian-based systems one also needs

* build-essential dh-make debhelper devscripts
* reprepro

On openSUSE 11.4+, in addition, one also needs to ensure the following is installed:


relaxngDatatype
docbook-utils docbook-simple
asciidoc
fuse-devel
docbook5
docbook5-xsl-stylesheets
libxml2-devel
xmlformat
xmlto
libxslt
libopenssl-devel

## Building packages

    $ make [component-name]-[rpm|deb]

## Building local YUM/APT repositories

    $ make [component-name]-[yum|apt]

##  Running the tests

WARNING: since testing packages requires installing them on a live
system it is highly recommended to use VMs for that.

Testing Bigtop is done using iTest framework. For more documentation
on iTest visit the iTest page
(http://cloudera.github.com/bigtop/iTest) but here's 2 steps to get started:

* install package testing iTest artifacts locally:

        cd test/src/smokes/package/ && mvn install -DskipTests -DskipITs -DperformRelease

* use those locally installed iTest package testing artifacts to run a suite:

        cd test/suites/package/ && mvn clean verify -Dcdh.repo.file.url.CentOS=XXX  -D'org.apache.maven-failsafe-plugin.testInclude=**/TestPackagesReadiness.*'

##  Contact us!

You can get in touch with us on the Bigtop mailing lists (http://bigtop.apache.org/mail-lists.html).
