summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/markdown/swiftkerbauth/swiftkerbauth_guide.md34
-rw-r--r--test/functional/swift_test_client.py1
-rw-r--r--test/functional_auth/swiftkerbauth/__init__.py0
-rw-r--r--test/functional_auth/swiftkerbauth/conf/account-server.conf36
-rw-r--r--test/functional_auth/swiftkerbauth/conf/container-server.conf36
-rw-r--r--test/functional_auth/swiftkerbauth/conf/fs.conf13
-rw-r--r--test/functional_auth/swiftkerbauth/conf/object-server.conf51
-rw-r--r--test/functional_auth/swiftkerbauth/conf/proxy-server.conf70
-rw-r--r--test/functional_auth/swiftkerbauth/conf/swift.conf84
-rw-r--r--test/functional_auth/swiftkerbauth/conf/test.conf49
-rw-r--r--test/functional_auth/swiftkerbauth/test_swkrbath_active.py93
-rwxr-xr-xtools/swkrbath_functional_tests.sh102
-rw-r--r--tox.ini4
13 files changed, 568 insertions, 5 deletions
diff --git a/doc/markdown/swiftkerbauth/swiftkerbauth_guide.md b/doc/markdown/swiftkerbauth/swiftkerbauth_guide.md
index 12845a6..5da1827 100644
--- a/doc/markdown/swiftkerbauth/swiftkerbauth_guide.md
+++ b/doc/markdown/swiftkerbauth/swiftkerbauth_guide.md
@@ -1,10 +1,11 @@
#swiftkerbauth
-* [Installing Kerberos module for Apache on IPA client] (#httpd-kerb-install)
-* [Creating HTTP Service Principal on IPA server] (#http-principal)
-* [Installing and configuring swiftkerbauth on IPA client] (#install-swiftkerbauth)
+* [Installing Kerberos module for Apache] (#httpd-kerb-install)
+* [Creating HTTP Service Principal] (#http-principal)
+* [Installing and configuring swiftkerbauth] (#install-swiftkerbauth)
* [Using swiftkerbauth] (#use-swiftkerbauth)
* [Configurable Parameters] (#config-swiftkerbauth)
+* [Functional tests] (#swfunctest)
<a name="httpd-kerb-install" />
## Installing Kerberos module for Apache on IPA client
@@ -487,5 +488,30 @@ Default value: passive
#### realm_name
This is applicable only when the auth_method=passive. This option specifies
-realm name if RHS server belongs to more than one realm and realm name is not
+realm name if storage server belongs to more than one realm and realm name is not
part of the username specified in X-Auth-User header.
+
+<a name="swfunctest" />
+##Functional tests for SwiftkerbAuth
+
+Functional tests to be run on the storage node after SwiftKerbAuth is setup using
+either IPA server or Windows AD. The gluster-swift/doc/markdown/swiftkerbauth
+directory contains the SwiftkerbAuth setup documents. There are two modes of
+working with SwiftKerbAuth. 'PASSIVE' mode indicates the client is outside the
+domain configured using SwiftKerbAuth. Client provides the 'Username' and
+'Password' while invoking a command. SwiftKerbAuth auth filter code then
+would get the ticket granting ticket from AD server or IPA server.
+In 'ACTIVE' mode of SwiftKerbAuth, User is already logged into storage node using
+its kerberos credentials. That user is authenticated across AD/IPA server.
+
+In PASSIVE mode all the generic functional tests are run. ACTIVE mode has a
+different way of acquiring Ticket Granting Ticket. And hence the different
+framework of functional tests there.
+
+The accounts, users, passwords must be prepared on AD/IPA server as per
+mentioned in test/functional_auth/swiftkerbauth/conf/test.conf
+
+Command to invoke SwiftKerbAuth functional tests is
+> $tox -e swfunctest
+
+This would run both ACTIVE and PASSIVE mode functional test cases.
diff --git a/test/functional/swift_test_client.py b/test/functional/swift_test_client.py
index ecb2a6d..a7c7c96 100644
--- a/test/functional/swift_test_client.py
+++ b/test/functional/swift_test_client.py
@@ -144,7 +144,6 @@ class Connection(object):
auth_scheme = 'https://' if self.auth_ssl else 'http://'
auth_netloc = "%s:%d" % (self.auth_host, self.auth_port)
auth_url = auth_scheme + auth_netloc + auth_path
-
(storage_url, storage_token) = get_auth(
auth_url, auth_user, self.password, snet=False,
tenant_name=self.account, auth_version=self.auth_version,
diff --git a/test/functional_auth/swiftkerbauth/__init__.py b/test/functional_auth/swiftkerbauth/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/functional_auth/swiftkerbauth/__init__.py
diff --git a/test/functional_auth/swiftkerbauth/conf/account-server.conf b/test/functional_auth/swiftkerbauth/conf/account-server.conf
new file mode 100644
index 0000000..9ad458a
--- /dev/null
+++ b/test/functional_auth/swiftkerbauth/conf/account-server.conf
@@ -0,0 +1,36 @@
+[DEFAULT]
+#
+# Default gluster mount point to be used for object store,can be changed by
+# setting the following value in {account,container,object}-server.conf files.
+# It is recommended to keep this value same for all the three services but can
+# be kept different if environment demands.
+devices = /mnt/gluster-object
+#
+# Once you are confident that your startup processes will always have your
+# gluster volumes properly mounted *before* the account-server workers start,
+# you can *consider* setting this value to "false" to reduce the per-request
+# overhead it can incur.
+mount_check = true
+bind_port = 6012
+#
+# Override swift's default behaviour for fallocate.
+disable_fallocate = true
+#
+# One or two workers should be sufficient for almost any installation of
+# Gluster.
+workers = 1
+
+[pipeline:main]
+pipeline = account-server
+
+[app:account-server]
+use = egg:gluster_swift#account
+user = root
+log_facility = LOG_LOCAL2
+log_level = WARN
+#
+# After ensuring things are running in a stable manner, you can turn off
+# normal request logging for the account server to unclutter the log
+# files. Warnings and errors will still be logged.
+log_requests = off
+
diff --git a/test/functional_auth/swiftkerbauth/conf/container-server.conf b/test/functional_auth/swiftkerbauth/conf/container-server.conf
new file mode 100644
index 0000000..a406b4d
--- /dev/null
+++ b/test/functional_auth/swiftkerbauth/conf/container-server.conf
@@ -0,0 +1,36 @@
+[DEFAULT]
+#
+# Default gluster mount point to be used for object store,can be changed by
+# setting the following value in {account,container,object}-server.conf files.
+# It is recommended to keep this value same for all the three services but can
+# be kept different if environment demands.
+devices = /mnt/gluster-object
+#
+# Once you are confident that your startup processes will always have your
+# gluster volumes properly mounted *before* the container-server workers
+# start, you can *consider* setting this value to "false" to reduce the
+# per-request overhead it can incur.
+mount_check = true
+bind_port = 6011
+#
+# Override swift's default behaviour for fallocate.
+disable_fallocate = true
+#
+# One or two workers should be sufficient for almost any installation of
+# Gluster.
+workers = 1
+
+[pipeline:main]
+pipeline = container-server
+
+[app:container-server]
+use = egg:gluster_swift#container
+user = root
+log_facility = LOG_LOCAL2
+log_level = WARN
+#
+# After ensuring things are running in a stable manner, you can turn off
+# normal request logging for the container server to unclutter the log
+# files. Warnings and errors will still be logged.
+log_requests = off
+
diff --git a/test/functional_auth/swiftkerbauth/conf/fs.conf b/test/functional_auth/swiftkerbauth/conf/fs.conf
new file mode 100644
index 0000000..6d2a791
--- /dev/null
+++ b/test/functional_auth/swiftkerbauth/conf/fs.conf
@@ -0,0 +1,13 @@
+[DEFAULT]
+#
+# IP address of a node in the GlusterFS server cluster hosting the
+# volumes to be served via Swift API.
+mount_ip = localhost
+
+# Performance optimization parameter. When turned off, the filesystem will
+# see a reduced number of stat calls, resulting in substantially faster
+# response time for GET and HEAD container requests on containers with large
+# numbers of objects, at the expense of an accurate count of combined bytes
+# used by all objects in the container. For most installations "off" works
+# fine.
+accurate_size_in_listing = off \ No newline at end of file
diff --git a/test/functional_auth/swiftkerbauth/conf/object-server.conf b/test/functional_auth/swiftkerbauth/conf/object-server.conf
new file mode 100644
index 0000000..d10d282
--- /dev/null
+++ b/test/functional_auth/swiftkerbauth/conf/object-server.conf
@@ -0,0 +1,51 @@
+[DEFAULT]
+#
+# Default gluster mount point to be used for object store,can be changed by
+# setting the following value in {account,container,object}-server.conf files.
+# It is recommended to keep this value same for all the three services but can
+# be kept different if environment demands.
+devices = /mnt/gluster-object
+#
+# Once you are confident that your startup processes will always have your
+# gluster volumes properly mounted *before* the object-server workers start,
+# you can *consider* setting this value to "false" to reduce the per-request
+# overhead it can incur.
+mount_check = true
+bind_port = 6010
+#
+# Maximum number of clients one worker can process simultaneously (it will
+# actually accept N + 1). Setting this to one (1) will only handle one request
+# at a time, without accepting another request concurrently. By increasing the
+# number of workers to a much higher value, one can prevent slow file system
+# operations for one request from starving other requests.
+max_clients = 1024
+#
+# If not doing the above, setting this value initially to match the number of
+# CPUs is a good starting point for determining the right value.
+workers = 1
+# Override swift's default behaviour for fallocate.
+disable_fallocate = true
+
+[pipeline:main]
+pipeline = object-server
+
+[app:object-server]
+use = egg:gluster_swift#object
+user = root
+log_facility = LOG_LOCAL2
+log_level = WARN
+#
+# For performance, after ensuring things are running in a stable manner, you
+# can turn off normal request logging for the object server to reduce the
+# per-request overhead and unclutter the log files. Warnings and errors will
+# still be logged.
+log_requests = off
+#
+# Adjust this value to match the stripe width of the underlying storage array
+# (not the stripe element size). This will provide a reasonable starting point
+# for tuning this value.
+disk_chunk_size = 65536
+#
+# Adjust this value match whatever is set for the disk_chunk_size initially.
+# This will provide a reasonable starting point for tuning this value.
+network_chunk_size = 65536
diff --git a/test/functional_auth/swiftkerbauth/conf/proxy-server.conf b/test/functional_auth/swiftkerbauth/conf/proxy-server.conf
new file mode 100644
index 0000000..e6f8aa1
--- /dev/null
+++ b/test/functional_auth/swiftkerbauth/conf/proxy-server.conf
@@ -0,0 +1,70 @@
+[DEFAULT]
+bind_port = 8080
+user = root
+# Consider using 1 worker per CPU
+workers = 1
+
+[pipeline:main]
+pipeline = catch_errors healthcheck proxy-logging cache proxy-logging kerbauth proxy-server
+
+[app:proxy-server]
+use = egg:gluster_swift#proxy
+log_facility = LOG_LOCAL1
+log_level = WARN
+# The API allows for account creation and deletion, but since Gluster/Swift
+# automounts a Gluster volume for a given account, there is no way to create
+# or delete an account. So leave this off.
+allow_account_management = false
+account_autocreate = true
+# Ensure the proxy server uses fast-POSTs since we don't need to make a copy
+# of the entire object given that all metadata is stored in the object
+# extended attributes (no .meta file used after creation) and no container
+# sync feature to present.
+object_post_as_copy = false
+# Only need to recheck the account exists once a day
+recheck_account_existence = 86400
+# May want to consider bumping this up if containers are created and destroyed
+# infrequently.
+recheck_container_existence = 60
+# Timeout clients that don't read or write to the proxy server after 5
+# seconds.
+client_timeout = 5
+# Give more time to connect to the object, container or account servers in
+# cases of high load.
+conn_timeout = 5
+# For high load situations, once connected to an object, container or account
+# server, allow for delays communicating with them.
+node_timeout = 60
+# May want to consider bumping up this value to 1 - 4 MB depending on how much
+# traffic is for multi-megabyte or gigabyte requests; perhaps matching the
+# stripe width (not stripe element size) of your storage volume is a good
+# starting point. See below for sizing information.
+object_chunk_size = 65536
+# If you do decide to increase the object_chunk_size, then consider lowering
+# this value to one. Up to "put_queue_length" object_chunk_size'd buffers can
+# be queued to the object server for processing. Given one proxy server worker
+# can handle up to 1,024 connections, by default, it will consume 10 * 65,536
+# * 1,024 bytes of memory in the worse case (default values). Be sure the
+# amount of memory available on the system can accommodate increased values
+# for object_chunk_size.
+put_queue_depth = 10
+
+[filter:catch_errors]
+use = egg:swift#catch_errors
+
+[filter:proxy-logging]
+use = egg:swift#proxy_logging
+access_log_level = WARN
+
+[filter:healthcheck]
+use = egg:swift#healthcheck
+
+[filter:kerbauth]
+use = egg:gluster_swift#kerbauth
+ext_authentication_url = http://client.rhelbox.com/cgi-bin/swift-auth
+
+[filter:cache]
+use = egg:swift#memcache
+# Update this line to contain a comma separated list of memcache servers
+# shared by all nodes running the proxy-server service.
+memcache_servers = localhost:11211
diff --git a/test/functional_auth/swiftkerbauth/conf/swift.conf b/test/functional_auth/swiftkerbauth/conf/swift.conf
new file mode 100644
index 0000000..0d25209
--- /dev/null
+++ b/test/functional_auth/swiftkerbauth/conf/swift.conf
@@ -0,0 +1,84 @@
+[DEFAULT]
+
+
+[swift-hash]
+# random unique string that can never change (DO NOT LOSE)
+swift_hash_path_suffix = gluster
+
+
+# The swift-constraints section sets the basic constraints on data
+# saved in the swift cluster.
+
+[swift-constraints]
+# max_file_size is the largest "normal" object that can be saved in
+# the cluster. This is also the limit on the size of each segment of
+# a "large" object when using the large object manifest support.
+# This value is set in bytes. Setting it to lower than 1MiB will cause
+# some tests to fail.
+# Default is 1 TiB = 2**30*1024
+
+max_file_size = 1099511627776
+
+# max_meta_name_length is the max number of bytes in the utf8 encoding
+# of the name portion of a metadata header.
+
+#max_meta_name_length = 128
+
+
+# max_meta_value_length is the max number of bytes in the utf8 encoding
+# of a metadata value
+
+#max_meta_value_length = 256
+
+
+# max_meta_count is the max number of metadata keys that can be stored
+# on a single account, container, or object
+
+#max_meta_count = 90
+
+
+# max_meta_overall_size is the max number of bytes in the utf8 encoding
+# of the metadata (keys + values)
+
+#max_meta_overall_size = 4096
+
+
+# max_object_name_length is the max number of bytes in the utf8 encoding of an
+# object name: Gluster FS can handle much longer file names, but the length
+# between the slashes of the URL is handled below. Remember that most web
+# clients can't handle anything greater than 2048, and those that do are
+# rather clumsy.
+
+max_object_name_length = 2048
+
+# max_object_name_component_length (GlusterFS) is the max number of bytes in
+# the utf8 encoding of an object name component (the part between the
+# slashes); this is a limit imposed by the underlying file system (for XFS it
+# is 255 bytes).
+
+max_object_name_component_length = 255
+
+# container_listing_limit is the default (and max) number of items
+# returned for a container listing request
+
+#container_listing_limit = 10000
+
+
+# account_listing_limit is the default (and max) number of items returned
+# for an account listing request
+
+#account_listing_limit = 10000
+
+
+# max_account_name_length is the max number of bytes in the utf8 encoding of
+# an account name: Gluster FS Filename limit (XFS limit?), must be the same
+# size as max_object_name_component_length above.
+
+max_account_name_length = 255
+
+
+# max_container_name_length is the max number of bytes in the utf8 encoding
+# of a container name: Gluster FS Filename limit (XFS limit?), must be the same
+# size as max_object_name_component_length above.
+
+max_container_name_length = 255
diff --git a/test/functional_auth/swiftkerbauth/conf/test.conf b/test/functional_auth/swiftkerbauth/conf/test.conf
new file mode 100644
index 0000000..643f2d1
--- /dev/null
+++ b/test/functional_auth/swiftkerbauth/conf/test.conf
@@ -0,0 +1,49 @@
+[func_test]
+# Swiftkerbauth configuration
+auth_host = 127.0.0.1
+auth_port = 8080
+auth_prefix = /auth/
+auth_scheme = http://
+auth_mode = passive
+auth_version = 1
+domain_name = RHELBOX.COM
+
+#All the accounts, users & passwords to be prepared on kerberos server.
+# Primary functional test account (needs admin access to the account)
+# Note: Account name to be prepared on kerberos server 'AUTH_accoun'
+account = test
+username = tester
+password = testing
+
+# User on a second account (needs admin access to the account)
+account2 = test2
+username2 = tester2
+password2 = testing2
+
+# User on same account as first, but without admin access
+username3 = tester3
+password3 = testing3
+
+# Default constraints if not defined here, the test runner will try
+# to set them from /etc/swift/swift.conf. If that file isn't found,
+# the test runner will skip tests that depend on these values.
+# Note that the cluster must have "sane" values for the test suite to pass.
+#max_file_size = 5368709122
+#max_meta_name_length = 128
+#max_meta_value_length = 256
+#max_meta_count = 90
+#max_meta_overall_size = 4096
+#max_object_name_length = 1024
+#container_listing_limit = 10000
+#account_listing_limit = 10000
+#max_account_name_length = 256
+#max_container_name_length = 256
+normalized_urls = True
+
+collate = C
+
+[unit_test]
+fake_syslog = False
+
+[probe_test]
+# check_server_timeout = 30
diff --git a/test/functional_auth/swiftkerbauth/test_swkrbath_active.py b/test/functional_auth/swiftkerbauth/test_swkrbath_active.py
new file mode 100644
index 0000000..86c79ef
--- /dev/null
+++ b/test/functional_auth/swiftkerbauth/test_swkrbath_active.py
@@ -0,0 +1,93 @@
+#!/usr/bin/python
+
+# Copyright (c) 2010-2014 OpenStack Foundation
+#
+# 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.
+
+import re
+import unittest
+from nose import SkipTest
+import commands
+import os
+from test import get_config
+from swift.common.bufferedhttp import http_connect_raw as http_connect
+
+config = get_config('func_test')
+
+class Utils:
+ @classmethod
+ def SwiftKerbAuthPrep(self,
+ user=config['username'],domain=config['domain_name'],\
+ passwd=config['password']):
+ username = '%s@%s' % (user, domain)
+ return commands.getstatusoutput('kinit %s <<< %s' % (username, passwd))
+
+ @classmethod
+ def SwiftKerbAuthCleanAll(self):
+ return commands.getstatusoutput('kdestroy')
+
+
+class TestSwKrbAthActive(unittest.TestCase):
+ def setUp(self):
+ #Perform kinit in active mode.
+ (status, output) = Utils.SwiftKerbAuthPrep()
+ self.assertEqual(status, 0, \
+ 'swkrbauth prep failed with valid credentials'+output)
+ self.auth_host = config['auth_host']
+ self.auth_port = int(config['auth_port'])
+ self.auth_prefix = config.get('auth_prefix', '/auth/')
+ self.auth_version = str(config.get('auth_version', '1'))
+ self.account_name = config['account']
+ self.username = config['username']
+ self.password = config['password']
+ self.auth_scheme = config['auth_scheme']
+
+ #Prepare auth_url. e.g. http://client.rhelbox.com:8080/auth/v1.0
+ if self.auth_version == "1":
+ self.auth_path = '%sv1.0' % (self.auth_prefix)
+ else:
+ self.auth_path = self.auth_prefix
+ self.auth_netloc = "%s:%d" % (self.auth_host, self.auth_port)
+ auth_url = self.auth_scheme + self.auth_netloc + self.auth_path
+
+ #Obtain the X-Auth-Token from kerberos server to use it in furhter
+ #testing
+ self.auth_token = None
+ (status, output) = commands.getstatusoutput('curl -v -u : --negotiate\
+ --location-trusted %s' % (auth_url))
+ self.assertEqual(status, 0, 'Token negotiation failed:' +output)
+ match = re.search('X-Auth-Token: AUTH.*', output)
+ if match:
+ self.auth_token = match.group(0).split(':')[1].strip()
+ else:
+ self.fail('No X-Auth-Token found, failed')
+
+ def tearDown(self):
+ Utils.SwiftKerbAuthCleanAll()
+
+
+ def _get_auth_token(self):
+ return {'X-Auth-Token' : self.auth_token}
+
+ def testGetAccounts(self):
+ #TODO: The test case is to perform GET on the account mentioned via
+ #configuration file. This is a sample test case. The whole test
+ #suite can be enhanced further to have further complicated test cases.
+ path = '/v1/AUTH_%s' % (config['account'])
+
+ headers = self._get_auth_token()
+ conn = http_connect(config['auth_host'], config['auth_port'], 'GET',
+ path, headers)
+ resp = conn.getresponse()
+ self.assertTrue(resp.status == 204)
diff --git a/tools/swkrbath_functional_tests.sh b/tools/swkrbath_functional_tests.sh
new file mode 100755
index 0000000..7abfd18
--- /dev/null
+++ b/tools/swkrbath_functional_tests.sh
@@ -0,0 +1,102 @@
+#!/bin/bash
+
+# Copyright (c) 2014 Red Hat, Inc.
+#
+# 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.
+
+# This program expects to be run by tox in a virtual python environment
+# so that it does not pollute the host development system
+
+sudo_env()
+{
+ sudo bash -c "PATH=$PATH $*"
+}
+
+cleanup()
+{
+ sudo service memcached stop
+ sudo_env swift-init main stop
+ sudo rm -rf /etc/swift > /dev/null 2>&1
+ for acct in /mnt/gluster-object/* ; do
+ sudo rm -rf /mnt/gluster-object/${acct}/* > /dev/null 2>&1
+ sudo setfattr -x user.swift.metadata /mnt/gluster-object/${acct} > /dev/null 2>&1
+ done
+}
+
+quit()
+{
+ echo "$1"
+ exit 1
+}
+
+
+fail()
+{
+ cleanup
+ quit "$1"
+}
+
+### MAIN ###
+
+# Only run if there is no configuration in the system
+if [ -x /etc/swift ] ; then
+ quit "/etc/swift exists, cannot run functional tests."
+fi
+
+# Check the directories exist
+DIRS="/mnt/gluster-object /mnt/gluster-object/test /mnt/gluster-object/test2 /mnt/gluster-object/gsmetadata"
+for d in $DIRS ; do
+ if [ ! -x $d ] ; then
+ quit "$d must exist on an XFS or GlusterFS volume"
+ fi
+done
+
+export SWIFT_TEST_CONFIG_FILE=/etc/swift/test.conf
+
+# Install the configuration files
+sudo mkdir /etc/swift > /dev/null 2>&1
+sudo cp -r test/functional_auth/swiftkerbauth/conf/* /etc/swift || fail "Unable to copy configuration files to /etc/swift"
+
+# Create the ring files
+accounts=""
+for acct in /mnt/gluster-object/* ; do
+ acct=`basename $acct`
+ accounts="$acct $accounts"
+done
+sudo_env gluster-swift-gen-builders $accounts || fail "Unable to create ring files"
+
+# Start the services
+sudo service memcached start || fail "Unable to start memcached"
+sudo_env swift-init main start || fail "Unable to start swift"
+
+mkdir functional_tests > /dev/null 2>&1
+
+echo "== SwiftKerbAuth: Functional Tests =="
+
+
+nosetests -v --exe \
+ --with-xunit \
+ --xunit-file functional_tests/gluster-swift-swiftkerbauth-generic-functional-TC-report.xml \
+ --with-html-output \
+ --html-out-file functional_tests/gluster-swift-swiftkerbauth-generic-functional-result.html \
+ test/functional_auth/swiftkerbauth || fail "Functional tests failed"
+#nosetests -v --exe \
+# --with-xunit \
+# --xunit-file functional_tests/gluster-swift-swiftkerbauth-functionalnosetests-TC-report.xml \
+# --with-html-output \
+# --html-out-file functional_tests/gluster-swift-swiftkerbauth-functionalnosetests-result.html \
+# test/functional || fail "Functional-nose tests failed"
+
+cleanup
+exit 0
diff --git a/tox.ini b/tox.ini
index ebcb5a1..a00a36a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -34,6 +34,10 @@ commands = bash tools/functional_tests.sh
changedir = {toxinidir}
commands = bash tools/keystone_functional_tests.sh
+[testenv:swfunctest]
+changedir = {toxinidir}
+commands = bash tools/swkrbath_functional_tests.sh
+
[testenv:pep8]
deps =
--download-cache={homedir}/.pipcache