2018-08-06 19:31:52 +00:00
# -*- coding: UTF-8 -*-
2017-11-07 20:00:35 +00:00
#
# Copyright (C) 2017 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
2018-02-12 14:56:24 +00:00
import os
2018-07-27 23:43:37 +00:00
from ConfigParser import SafeConfigParser , NoOptionError
2018-02-10 01:39:42 +00:00
from glob import glob
2017-11-13 18:32:52 +00:00
import shutil
2017-11-08 01:09:56 +00:00
import tempfile
2018-02-10 01:39:42 +00:00
import time
2017-11-08 01:09:56 +00:00
from threading import Lock
2017-11-07 20:00:35 +00:00
import unittest
from flask import json
2017-11-10 16:25:57 +00:00
import pytoml as toml
2018-02-10 01:39:42 +00:00
from pylorax . api . config import configure , make_yum_dirs , make_queue_dirs
2018-08-08 14:57:46 +00:00
from pylorax . api . errors import * # pylint: disable=wildcard-import
2018-02-10 01:39:42 +00:00
from pylorax . api . queue import start_queue_monitor
2017-11-08 01:09:56 +00:00
from pylorax . api . recipes import open_or_create_repo , commit_recipe_directory
2017-11-22 18:29:33 +00:00
from pylorax . api . server import server , GitLock , YumLock
from pylorax . api . yumbase import get_base_object
2017-11-10 16:25:57 +00:00
from pylorax . sysutils import joinpaths
2017-11-07 20:00:35 +00:00
2018-08-06 19:31:52 +00:00
# Used for testing UTF-8 input support
UTF8_TEST_STRING = " I w 𝒊 ll 𝟉ο𝘁 𝛠 a 𝔰 ꜱ 𝘁 𝒉 𝝸 𝚜 " . decode ( " utf-8 " )
2018-07-27 23:43:37 +00:00
def get_system_repo ( ) :
""" Get an enabled system repo from /etc/yum.repos.d/*repo
This will be used for test_projects_source_01_delete_system ( )
"""
# The sources delete test needs the name of a system repo, get it from /etc/yum.repos.d/
for sys_repo in sorted ( glob ( " /etc/yum.repos.d/*repo " ) ) :
cfg = SafeConfigParser ( )
cfg . read ( sys_repo )
for section in cfg . sections ( ) :
try :
if cfg . get ( section , " enabled " ) == " 1 " :
# The API only supports repo filenames, return that.
return os . path . basename ( sys_repo ) [ : - 5 ]
except NoOptionError :
pass
# Failed to find one, fall back to using base
return " base "
2017-11-07 20:00:35 +00:00
class ServerTestCase ( unittest . TestCase ) :
@classmethod
def setUpClass ( self ) :
2017-11-08 01:09:56 +00:00
repo_dir = tempfile . mkdtemp ( prefix = " lorax.test.repo. " )
server . config [ " REPO_DIR " ] = repo_dir
repo = open_or_create_repo ( server . config [ " REPO_DIR " ] )
server . config [ " GITLOCK " ] = GitLock ( repo = repo , lock = Lock ( ) , dir = repo_dir )
2017-11-22 18:29:33 +00:00
server . config [ " COMPOSER_CFG " ] = configure ( root_dir = repo_dir , test_config = True )
2018-02-10 01:39:42 +00:00
os . makedirs ( joinpaths ( server . config [ " COMPOSER_CFG " ] . get ( " composer " , " share_dir " ) , " composer " ) )
errors = make_queue_dirs ( server . config [ " COMPOSER_CFG " ] , 0 )
if errors :
raise RuntimeError ( " \n " . join ( errors ) )
2018-02-05 18:40:39 +00:00
make_yum_dirs ( server . config [ " COMPOSER_CFG " ] )
2018-05-29 19:22:34 +00:00
# copy over the test yum repositories
yum_repo_dir = server . config [ " COMPOSER_CFG " ] . get ( " composer " , " repo_dir " )
for f in glob ( " ./tests/pylorax/repos/*.repo " ) :
shutil . copy2 ( f , yum_repo_dir )
# yum repo baseurl has to point to an absolute directory, so we use /tmp/lorax-empty-repo/ in the files
# and create an empty repository
os . makedirs ( " /tmp/lorax-empty-repo/ " )
2018-07-26 22:06:05 +00:00
rc = os . system ( " createrepo_c /tmp/lorax-empty-repo/ " )
if rc != 0 :
shutil . rmtree ( " /tmp/lorax-empty-repo/ " )
raise RuntimeError ( " Problem running createrepo_c, is it installed " )
2018-05-29 19:22:34 +00:00
2017-11-22 18:29:33 +00:00
yb = get_base_object ( server . config [ " COMPOSER_CFG " ] )
server . config [ " YUMLOCK " ] = YumLock ( yb = yb , lock = Lock ( ) )
2018-07-12 16:25:22 +00:00
# Include a message in /api/status output
server . config [ " TEMPLATE_ERRORS " ] = [ " Test message " ]
2017-11-07 20:00:35 +00:00
server . config [ ' TESTING ' ] = True
self . server = server . test_client ( )
2018-05-08 16:25:44 +00:00
self . repo_dir = repo_dir
2017-11-07 20:00:35 +00:00
2018-03-28 19:40:10 +00:00
self . examples_path = " ./tests/pylorax/blueprints/ "
2017-11-10 16:25:57 +00:00
2018-02-10 01:39:42 +00:00
# Copy the shared files over to the directory tree we are using
share_path = " ./share/composer/ "
for f in glob ( joinpaths ( share_path , " * " ) ) :
shutil . copy ( f , joinpaths ( server . config [ " COMPOSER_CFG " ] . get ( " composer " , " share_dir " ) , " composer " ) )
2018-03-28 19:40:10 +00:00
# Import the example blueprints
2017-11-10 16:25:57 +00:00
commit_recipe_directory ( server . config [ " GITLOCK " ] . repo , " master " , self . examples_path )
2017-11-08 01:09:56 +00:00
2018-07-26 22:06:05 +00:00
# The sources delete test needs the name of a system repo, get it from /etc/yum.repos.d/
2018-07-27 23:43:37 +00:00
self . system_repo = get_system_repo ( )
2018-07-26 22:06:05 +00:00
2018-02-10 01:39:42 +00:00
start_queue_monitor ( server . config [ " COMPOSER_CFG " ] , 0 , 0 )
2017-11-07 20:00:35 +00:00
@classmethod
def tearDownClass ( self ) :
2017-11-13 18:32:52 +00:00
shutil . rmtree ( server . config [ " REPO_DIR " ] )
2018-05-29 19:22:34 +00:00
shutil . rmtree ( " /tmp/lorax-empty-repo/ " )
2017-11-07 20:00:35 +00:00
2017-11-13 20:42:59 +00:00
def test_01_status ( self ) :
2018-04-03 00:04:08 +00:00
""" Test the /api/status route """
2018-07-12 16:25:22 +00:00
status_fields = [ " build " , " api " , " db_version " , " schema_version " , " db_supported " , " backend " , " msgs " ]
2018-04-03 00:04:08 +00:00
resp = self . server . get ( " /api/status " )
2017-11-07 20:00:35 +00:00
data = json . loads ( resp . data )
2018-07-12 16:25:22 +00:00
# Make sure the fields are present
2018-04-03 00:04:08 +00:00
self . assertEqual ( sorted ( data . keys ( ) ) , sorted ( status_fields ) )
2017-11-08 01:09:56 +00:00
2018-07-12 16:25:22 +00:00
# Check for test message
self . assertEqual ( data [ " msgs " ] , [ " Test message " ] )
2018-03-28 19:40:10 +00:00
def test_02_blueprints_list ( self ) :
2018-03-27 23:42:36 +00:00
""" Test the /api/v0/blueprints/list route """
2018-05-08 16:25:44 +00:00
list_dict = { " blueprints " : [ " atlas " , " custom-base " , " development " , " glusterfs " , " http-server " ,
" jboss " , " kubernetes " ] , " limit " : 20 , " offset " : 0 , " total " : 7 }
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/list " )
2017-11-08 01:09:56 +00:00
data = json . loads ( resp . data )
self . assertEqual ( data , list_dict )
2017-11-09 01:38:12 +00:00
2018-03-28 19:40:10 +00:00
def test_03_blueprints_info ( self ) :
2018-03-27 23:42:36 +00:00
""" Test the /api/v0/blueprints/info route """
2017-11-09 01:38:12 +00:00
info_dict_1 = { " changes " : [ { " changed " : False , " name " : " http-server " } ] ,
" errors " : [ ] ,
2018-03-28 19:40:10 +00:00
" blueprints " : [ { " description " : " An example http server with PHP and MySQL support. " ,
2017-11-09 01:38:12 +00:00
" modules " : [ { " name " : " httpd " , " version " : " 2.4.* " } ,
{ " name " : " mod_auth_kerb " , " version " : " 5.4 " } ,
{ " name " : " mod_ssl " , " version " : " 2.4.* " } ,
{ " name " : " php " , " version " : " 5.4.* " } ,
{ " name " : " php-mysql " , " version " : " 5.4.* " } ] ,
" name " : " http-server " ,
2018-05-19 00:28:20 +00:00
" packages " : [ { " name " : " openssh-server " , " version " : " 7.* " } ,
{ " name " : " rsync " , " version " : " 3.1.* " } ,
{ " name " : " tmux " , " version " : " 1.8 " } ] ,
2018-07-11 18:07:45 +00:00
" groups " : [ ] ,
2017-11-10 22:45:13 +00:00
" version " : " 0.0.1 " } ] }
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/info/http-server " )
2017-11-09 01:38:12 +00:00
data = json . loads ( resp . data )
self . assertEqual ( data , info_dict_1 )
info_dict_2 = { " changes " : [ { " changed " : False , " name " : " glusterfs " } ,
{ " changed " : False , " name " : " http-server " } ] ,
" errors " : [ ] ,
2018-03-28 19:40:10 +00:00
" blueprints " : [ { " description " : " An example GlusterFS server with samba " ,
2018-07-26 22:06:05 +00:00
" modules " : [ { " name " : " glusterfs " , " version " : " 3.*.* " } ,
{ " name " : " glusterfs-cli " , " version " : " 3.*.* " } ] ,
2017-11-09 01:38:12 +00:00
" name " : " glusterfs " ,
2018-07-26 22:06:05 +00:00
" packages " : [ { " name " : " samba " , " version " : " 4.*.* " } ] ,
2018-07-11 18:07:45 +00:00
" groups " : [ ] ,
2017-11-09 01:38:12 +00:00
" version " : " 0.0.1 " } ,
{ " description " : " An example http server with PHP and MySQL support. " ,
" modules " : [ { " name " : " httpd " , " version " : " 2.4.* " } ,
{ " name " : " mod_auth_kerb " , " version " : " 5.4 " } ,
{ " name " : " mod_ssl " , " version " : " 2.4.* " } ,
{ " name " : " php " , " version " : " 5.4.* " } ,
{ " name " : " php-mysql " , " version " : " 5.4.* " } ] ,
" name " : " http-server " ,
2018-05-19 00:28:20 +00:00
" packages " : [ { " name " : " openssh-server " , " version " : " 7.* " } ,
{ " name " : " rsync " , " version " : " 3.1.* " } ,
{ " name " : " tmux " , " version " : " 1.8 " } ] ,
2018-07-11 18:07:45 +00:00
" groups " : [ ] ,
2017-11-10 22:45:13 +00:00
" version " : " 0.0.1 " } ,
2017-11-09 01:38:12 +00:00
] }
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/info/http-server,glusterfs " )
2017-11-09 01:38:12 +00:00
data = json . loads ( resp . data )
self . assertEqual ( data , info_dict_2 )
info_dict_3 = { " changes " : [ ] ,
2018-08-08 19:41:40 +00:00
" errors " : [ { " id " : UNKNOWN_BLUEPRINT , " msg " : " missing-blueprint: No commits for missing-blueprint.toml on the master branch. " } ] ,
2018-03-28 19:40:10 +00:00
" blueprints " : [ ]
2017-11-09 01:38:12 +00:00
}
2018-03-28 19:40:10 +00:00
resp = self . server . get ( " /api/v0/blueprints/info/missing-blueprint " )
2017-11-09 01:38:12 +00:00
data = json . loads ( resp . data )
self . assertEqual ( data , info_dict_3 )
2018-03-28 19:40:10 +00:00
def test_04_blueprints_changes ( self ) :
2018-03-27 23:42:36 +00:00
""" Test the /api/v0/blueprints/changes route """
resp = self . server . get ( " /api/v0/blueprints/changes/http-server " )
2017-11-10 02:43:42 +00:00
data = json . loads ( resp . data )
# Can't compare a whole dict since commit hash and timestamps will change.
# Should have 1 commit (for now), with a matching message.
self . assertEqual ( data [ " limit " ] , 20 )
self . assertEqual ( data [ " offset " ] , 0 )
self . assertEqual ( len ( data [ " errors " ] ) , 0 )
2018-03-28 19:40:10 +00:00
self . assertEqual ( len ( data [ " blueprints " ] ) , 1 )
self . assertEqual ( data [ " blueprints " ] [ 0 ] [ " name " ] , " http-server " )
self . assertEqual ( len ( data [ " blueprints " ] [ 0 ] [ " changes " ] ) , 1 )
2017-11-10 16:25:57 +00:00
2018-03-28 19:40:10 +00:00
def test_04a_blueprints_diff_empty_ws ( self ) :
2018-02-16 20:11:25 +00:00
""" Test the /api/v0/diff/NEWEST/WORKSPACE with empty workspace """
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/diff/glusterfs/NEWEST/WORKSPACE " )
2018-02-16 20:11:25 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data , { " diff " : [ ] } )
2018-03-28 19:40:10 +00:00
def test_05_blueprints_new_json ( self ) :
""" Test the /api/v0/blueprints/new route with json blueprint """
test_blueprint = { " description " : " An example GlusterFS server with samba " ,
2017-11-10 16:25:57 +00:00
" name " : " glusterfs " ,
" version " : " 0.2.0 " ,
2018-07-26 22:06:05 +00:00
" modules " : [ { " name " : " glusterfs " , " version " : " 3.*.* " } ,
{ " name " : " glusterfs-cli " , " version " : " 3.*.* " } ] ,
" packages " : [ { " name " : " samba " , " version " : " 4.*.* " } ,
2018-07-11 18:07:45 +00:00
{ " name " : " tmux " , " version " : " 1.8 " } ] ,
" groups " : [ ] }
2017-11-10 16:25:57 +00:00
2018-03-27 23:42:36 +00:00
resp = self . server . post ( " /api/v0/blueprints/new " ,
2018-03-28 19:40:10 +00:00
data = json . dumps ( test_blueprint ) ,
2017-11-10 16:25:57 +00:00
content_type = " application/json " )
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/info/glusterfs " )
2017-11-10 16:25:57 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertEqual ( len ( blueprints ) , 1 )
self . assertEqual ( blueprints [ 0 ] , test_blueprint )
2017-11-10 16:25:57 +00:00
2018-03-28 19:40:10 +00:00
def test_06_blueprints_new_toml ( self ) :
""" Test the /api/v0/blueprints/new route with toml blueprint """
test_blueprint = open ( joinpaths ( self . examples_path , " glusterfs.toml " ) , " rb " ) . read ( )
2018-03-27 23:42:36 +00:00
resp = self . server . post ( " /api/v0/blueprints/new " ,
2018-03-28 19:40:10 +00:00
data = test_blueprint ,
2017-11-10 16:25:57 +00:00
content_type = " text/x-toml " )
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/info/glusterfs " )
2017-11-10 16:25:57 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertEqual ( len ( blueprints ) , 1 )
2017-11-10 16:25:57 +00:00
2018-03-28 19:40:10 +00:00
# Returned blueprint has had its version bumped to 0.2.1
test_blueprint = toml . loads ( test_blueprint )
test_blueprint [ " version " ] = " 0.2.1 "
2017-11-10 16:25:57 +00:00
2018-07-11 18:07:45 +00:00
# The test_blueprint generated by toml.loads will not have any groups property
# defined, since there are no groups listed. However, /api/v0/blueprints/new will
# return an object with groups=[]. So, add that here to keep the equality test
# working.
test_blueprint [ " groups " ] = [ ]
2018-03-28 19:40:10 +00:00
self . assertEqual ( blueprints [ 0 ] , test_blueprint )
2017-11-13 18:32:52 +00:00
2018-03-28 19:40:10 +00:00
def test_07_blueprints_ws_json ( self ) :
""" Test the /api/v0/blueprints/workspace route with json blueprint """
test_blueprint = { " description " : " An example GlusterFS server with samba, ws version " ,
2017-11-13 18:32:52 +00:00
" name " : " glusterfs " ,
" version " : " 0.3.0 " ,
2018-07-26 22:06:05 +00:00
" modules " : [ { " name " : " glusterfs " , " version " : " 3.*.* " } ,
{ " name " : " glusterfs-cli " , " version " : " 3.*.* " } ] ,
" packages " : [ { " name " : " samba " , " version " : " 4.*.* " } ,
2018-07-11 18:07:45 +00:00
{ " name " : " tmux " , " version " : " 1.8 " } ] ,
" groups " : [ ] }
2017-11-13 18:32:52 +00:00
2018-03-27 23:42:36 +00:00
resp = self . server . post ( " /api/v0/blueprints/workspace " ,
2018-03-28 19:40:10 +00:00
data = json . dumps ( test_blueprint ) ,
2017-11-13 18:32:52 +00:00
content_type = " application/json " )
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/info/glusterfs " )
2017-11-13 18:32:52 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertEqual ( len ( blueprints ) , 1 )
self . assertEqual ( blueprints [ 0 ] , test_blueprint )
2017-11-13 18:32:52 +00:00
changes = data . get ( " changes " )
self . assertEqual ( len ( changes ) , 1 )
self . assertEqual ( changes [ 0 ] , { " name " : " glusterfs " , " changed " : True } )
2018-03-28 19:40:10 +00:00
def test_08_blueprints_ws_toml ( self ) :
""" Test the /api/v0/blueprints/workspace route with toml blueprint """
test_blueprint = { " description " : " An example GlusterFS server with samba, ws version " ,
2017-11-13 18:32:52 +00:00
" name " : " glusterfs " ,
" version " : " 0.4.0 " ,
2018-07-26 22:06:05 +00:00
" modules " : [ { " name " : " glusterfs " , " version " : " 3.*.* " } ,
{ " name " : " glusterfs-cli " , " version " : " 3.*.* " } ] ,
" packages " : [ { " name " : " samba " , " version " : " 4.*.* " } ,
2018-07-11 18:07:45 +00:00
{ " name " : " tmux " , " version " : " 1.8 " } ] ,
" groups " : [ ] }
2017-11-13 18:32:52 +00:00
2018-03-27 23:42:36 +00:00
resp = self . server . post ( " /api/v0/blueprints/workspace " ,
2018-03-28 19:40:10 +00:00
data = json . dumps ( test_blueprint ) ,
2017-11-13 18:32:52 +00:00
content_type = " application/json " )
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/info/glusterfs " )
2017-11-13 18:32:52 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertEqual ( len ( blueprints ) , 1 )
self . assertEqual ( blueprints [ 0 ] , test_blueprint )
2017-11-13 18:32:52 +00:00
changes = data . get ( " changes " )
self . assertEqual ( len ( changes ) , 1 )
self . assertEqual ( changes [ 0 ] , { " name " : " glusterfs " , " changed " : True } )
2017-11-13 19:21:14 +00:00
2018-03-28 19:40:10 +00:00
def test_09_blueprints_ws_delete ( self ) :
2018-03-27 23:42:36 +00:00
""" Test DELETE /api/v0/blueprints/workspace/<blueprint_name> """
2018-03-28 19:40:10 +00:00
# Write to the workspace first, just use the test_blueprints_ws_json test for this
self . test_07_blueprints_ws_json ( )
2017-11-13 19:21:14 +00:00
# Delete it
2018-03-27 23:42:36 +00:00
resp = self . server . delete ( " /api/v0/blueprints/workspace/glusterfs " )
2017-11-13 19:21:14 +00:00
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
# Make sure it isn't the workspace copy and that changed is False
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/info/glusterfs " )
2017-11-13 19:21:14 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertEqual ( len ( blueprints ) , 1 )
self . assertEqual ( blueprints [ 0 ] [ " version " ] , " 0.2.1 " )
2017-11-13 19:21:14 +00:00
changes = data . get ( " changes " )
self . assertEqual ( len ( changes ) , 1 )
self . assertEqual ( changes [ 0 ] , { " name " : " glusterfs " , " changed " : False } )
2017-11-13 20:42:59 +00:00
2018-03-28 19:40:10 +00:00
def test_10_blueprints_delete ( self ) :
2018-03-27 23:42:36 +00:00
""" Test DELETE /api/v0/blueprints/delete/<blueprint_name> """
resp = self . server . delete ( " /api/v0/blueprints/delete/glusterfs " )
2017-11-13 20:42:59 +00:00
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
2018-03-28 19:40:10 +00:00
# Make sure glusterfs is no longer in the list of blueprints
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/list " )
2017-11-13 20:42:59 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertEqual ( " glusterfs " in blueprints , False )
2017-11-13 23:44:46 +00:00
2018-03-28 19:40:10 +00:00
def test_11_blueprints_undo ( self ) :
2018-03-27 23:42:36 +00:00
""" Test POST /api/v0/blueprints/undo/<blueprint_name>/<commit> """
resp = self . server . get ( " /api/v0/blueprints/changes/glusterfs " )
2017-11-13 23:44:46 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
# Revert it to the first commit
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertNotEqual ( blueprints , None )
changes = blueprints [ 0 ] . get ( " changes " )
2017-11-13 23:44:46 +00:00
self . assertEqual ( len ( changes ) > 1 , True )
# Revert it to the first commit
commit = changes [ - 1 ] [ " commit " ]
2018-03-27 23:42:36 +00:00
resp = self . server . post ( " /api/v0/blueprints/undo/glusterfs/ %s " % commit )
2017-11-13 23:44:46 +00:00
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/changes/glusterfs " )
2017-11-13 23:44:46 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertNotEqual ( blueprints , None )
changes = blueprints [ 0 ] . get ( " changes " )
2017-11-13 23:44:46 +00:00
self . assertEqual ( len ( changes ) > 1 , True )
2018-03-28 19:40:10 +00:00
expected_msg = " glusterfs.toml reverted to commit %s " % commit
2017-11-13 23:44:46 +00:00
self . assertEqual ( changes [ 0 ] [ " message " ] , expected_msg )
2017-11-14 00:34:23 +00:00
2018-03-28 19:40:10 +00:00
def test_12_blueprints_tag ( self ) :
2018-03-27 23:42:36 +00:00
""" Test POST /api/v0/blueprints/tag/<blueprint_name> """
resp = self . server . post ( " /api/v0/blueprints/tag/glusterfs " )
2017-11-14 00:34:23 +00:00
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/changes/glusterfs " )
2017-11-14 00:34:23 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
# Revert it to the first commit
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertNotEqual ( blueprints , None )
changes = blueprints [ 0 ] . get ( " changes " )
2017-11-14 00:34:23 +00:00
self . assertEqual ( len ( changes ) > 1 , True )
self . assertEqual ( changes [ 0 ] [ " revision " ] , 1 )
2017-11-15 01:01:35 +00:00
2018-03-28 19:40:10 +00:00
def test_13_blueprints_diff ( self ) :
2018-03-27 23:42:36 +00:00
""" Test /api/v0/blueprints/diff/<blueprint_name>/<from_commit>/<to_commit> """
resp = self . server . get ( " /api/v0/blueprints/changes/glusterfs " )
2017-11-15 01:01:35 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertNotEqual ( blueprints , None )
changes = blueprints [ 0 ] . get ( " changes " )
2017-11-15 01:01:35 +00:00
self . assertEqual ( len ( changes ) > = 2 , True )
from_commit = changes [ 1 ] . get ( " commit " )
self . assertNotEqual ( from_commit , None )
to_commit = changes [ 0 ] . get ( " commit " )
self . assertNotEqual ( to_commit , None )
# Get the differences between the two commits
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/diff/glusterfs/ %s / %s " % ( from_commit , to_commit ) )
2017-11-15 01:01:35 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data , { " diff " : [ { " new " : { " Version " : " 0.0.1 " } , " old " : { " Version " : " 0.2.1 " } } ] } )
# Write to the workspace and check the diff
2018-03-28 19:40:10 +00:00
test_blueprint = { " description " : " An example GlusterFS server with samba, ws version " ,
2017-11-15 01:01:35 +00:00
" name " : " glusterfs " ,
" version " : " 0.3.0 " ,
2018-07-26 22:06:05 +00:00
" modules " : [ { " name " : " glusterfs " , " version " : " 3.*.* " } ,
{ " name " : " glusterfs-cli " , " version " : " 3.*.* " } ] ,
" packages " : [ { " name " : " samba " , " version " : " 4.*.* " } ,
2018-05-19 00:28:20 +00:00
{ " name " : " tmux " , " version " : " 1.8 " } ] }
2017-11-15 01:01:35 +00:00
2018-03-27 23:42:36 +00:00
resp = self . server . post ( " /api/v0/blueprints/workspace " ,
2018-03-28 19:40:10 +00:00
data = json . dumps ( test_blueprint ) ,
2017-11-15 01:01:35 +00:00
content_type = " application/json " )
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
# Get the differences between the newest commit and the workspace
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/diff/glusterfs/NEWEST/WORKSPACE " )
2017-11-15 01:01:35 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
result = { " diff " : [ { " new " : { " Description " : " An example GlusterFS server with samba, ws version " } ,
" old " : { " Description " : " An example GlusterFS server with samba " } } ,
{ " new " : { " Version " : " 0.3.0 " } ,
" old " : { " Version " : " 0.0.1 " } } ,
2018-05-19 00:28:20 +00:00
{ " new " : { " Package " : { " version " : " 1.8 " , " name " : " tmux " } } ,
2017-11-15 01:01:35 +00:00
" old " : None } ] }
self . assertEqual ( data , result )
2017-11-22 18:29:33 +00:00
2018-03-28 19:40:10 +00:00
def test_14_blueprints_depsolve ( self ) :
2018-03-27 23:42:36 +00:00
""" Test /api/v0/blueprints/depsolve/<blueprint_names> """
resp = self . server . get ( " /api/v0/blueprints/depsolve/glusterfs " )
2017-11-22 21:50:02 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertNotEqual ( blueprints , None )
self . assertEqual ( len ( blueprints ) , 1 )
2018-05-19 00:28:20 +00:00
self . assertTrue ( len ( blueprints [ 0 ] [ " blueprint " ] [ " modules " ] ) > 0 )
2018-03-28 19:40:10 +00:00
self . assertEqual ( blueprints [ 0 ] [ " blueprint " ] [ " name " ] , " glusterfs " )
self . assertEqual ( len ( blueprints [ 0 ] [ " dependencies " ] ) > 10 , True )
2017-12-12 10:38:56 +00:00
self . assertFalse ( data . get ( " errors " ) )
2018-03-28 19:40:10 +00:00
def test_14_blueprints_depsolve_empty ( self ) :
""" Test /api/v0/blueprints/depsolve/<blueprint_names> on empty blueprint """
test_blueprint = { " description " : " An empty blueprint " ,
2017-12-12 10:38:56 +00:00
" name " : " void " ,
" version " : " 0.1.0 " }
2018-03-27 23:42:36 +00:00
resp = self . server . post ( " /api/v0/blueprints/new " ,
2018-03-28 19:40:10 +00:00
data = json . dumps ( test_blueprint ) ,
2017-12-12 10:38:56 +00:00
content_type = " application/json " )
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/depsolve/void " )
2017-12-12 10:38:56 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertNotEqual ( blueprints , None )
self . assertEqual ( len ( blueprints ) , 1 )
self . assertEqual ( blueprints [ 0 ] [ " blueprint " ] [ " name " ] , " void " )
self . assertEqual ( blueprints [ 0 ] [ " blueprint " ] [ " packages " ] , [ ] )
self . assertEqual ( blueprints [ 0 ] [ " blueprint " ] [ " modules " ] , [ ] )
self . assertEqual ( blueprints [ 0 ] [ " dependencies " ] , [ ] )
2017-12-12 10:38:56 +00:00
self . assertFalse ( data . get ( " errors " ) )
2017-11-22 21:50:02 +00:00
2018-03-28 19:40:10 +00:00
def test_15_blueprints_freeze ( self ) :
2018-03-27 23:42:36 +00:00
""" Test /api/v0/blueprints/freeze/<blueprint_names> """
resp = self . server . get ( " /api/v0/blueprints/freeze/glusterfs " )
2017-11-22 22:46:43 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertNotEqual ( blueprints , None )
self . assertEqual ( len ( blueprints ) , 1 )
2018-05-19 00:28:20 +00:00
self . assertTrue ( len ( blueprints [ 0 ] [ " blueprint " ] [ " modules " ] ) > 0 )
2018-03-28 19:40:10 +00:00
self . assertEqual ( blueprints [ 0 ] [ " blueprint " ] [ " name " ] , " glusterfs " )
evra = blueprints [ 0 ] [ " blueprint " ] [ " modules " ] [ 0 ] [ " version " ]
2017-11-22 22:46:43 +00:00
self . assertEqual ( len ( evra ) > 10 , True )
2017-11-22 18:29:33 +00:00
def test_projects_list ( self ) :
""" Test /api/v0/projects/list """
resp = self . server . get ( " /api/v0/projects/list " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
projects = data . get ( " projects " )
self . assertEqual ( len ( projects ) > 10 , True )
def test_projects_info ( self ) :
""" Test /api/v0/projects/info/<project_names> """
resp = self . server . get ( " /api/v0/projects/info/bash " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
projects = data . get ( " projects " )
self . assertEqual ( len ( projects ) , 1 )
2018-05-19 00:28:20 +00:00
self . assertTrue ( len ( projects [ 0 ] [ " builds " ] ) > 0 )
2017-11-22 18:29:33 +00:00
self . assertEqual ( projects [ 0 ] [ " name " ] , " bash " )
self . assertEqual ( projects [ 0 ] [ " builds " ] [ 0 ] [ " source " ] [ " license " ] , " GPLv3+ " )
def test_projects_depsolve ( self ) :
""" Test /api/v0/projects/depsolve/<project_names> """
resp = self . server . get ( " /api/v0/projects/depsolve/bash " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
deps = data . get ( " projects " )
self . assertEqual ( len ( deps ) > 10 , True )
2018-07-11 18:07:45 +00:00
self . assertTrue ( " basesystem " in [ dep [ " name " ] for dep in deps ] )
2017-11-22 18:29:33 +00:00
2018-05-29 19:22:34 +00:00
def test_projects_source_00_list ( self ) :
""" Test /api/v0/projects/source/list """
resp = self . server . get ( " /api/v0/projects/source/list " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-07-26 22:06:05 +00:00
# Make sure it lists some common sources
for r in [ " lorax-1 " , " lorax-2 " , " lorax-3 " , " lorax-4 " , " other-repo " , " single-repo " ] :
self . assertTrue ( r in data [ " sources " ] )
2018-05-29 19:22:34 +00:00
def test_projects_source_00_info ( self ) :
""" Test /api/v0/projects/source/info """
resp = self . server . get ( " /api/v0/projects/source/info/single-repo " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
sources = data [ " sources " ]
self . assertTrue ( " single-repo " in sources )
def test_projects_source_00_new_json ( self ) :
""" Test /api/v0/projects/source/new with a new json source """
json_source = open ( " ./tests/pylorax/source/test-repo.json " ) . read ( )
self . assertTrue ( len ( json_source ) > 0 )
resp = self . server . post ( " /api/v0/projects/source/new " ,
data = json_source ,
content_type = " application/json " )
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
2018-05-30 16:48:37 +00:00
# Is it listed?
resp = self . server . get ( " /api/v0/projects/source/list " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
sources = data [ " sources " ]
self . assertTrue ( " new-repo-1 " in sources )
2018-05-29 19:22:34 +00:00
def test_projects_source_00_new_toml ( self ) :
""" Test /api/v0/projects/source/new with a new toml source """
toml_source = open ( " ./tests/pylorax/source/test-repo.toml " ) . read ( )
self . assertTrue ( len ( toml_source ) > 0 )
resp = self . server . post ( " /api/v0/projects/source/new " ,
data = toml_source ,
content_type = " text/x-toml " )
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
2018-05-30 16:48:37 +00:00
# Is it listed?
resp = self . server . get ( " /api/v0/projects/source/list " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
sources = data [ " sources " ]
self . assertTrue ( " new-repo-2 " in sources )
2018-05-29 19:22:34 +00:00
def test_projects_source_00_replace ( self ) :
""" Test /api/v0/projects/source/new with a replacement source """
toml_source = open ( " ./tests/pylorax/source/replace-repo.toml " ) . read ( )
self . assertTrue ( len ( toml_source ) > 0 )
resp = self . server . post ( " /api/v0/projects/source/new " ,
data = toml_source ,
content_type = " text/x-toml " )
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
# Check to see if it was really changed
resp = self . server . get ( " /api/v0/projects/source/info/single-repo " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
sources = data [ " sources " ]
self . assertTrue ( " single-repo " in sources )
repo = sources [ " single-repo " ]
self . assertEqual ( repo [ " check_ssl " ] , False )
self . assertTrue ( " gpgkey_urls " not in repo )
2018-05-30 22:13:02 +00:00
def test_projects_source_00_bad_url ( self ) :
""" Test /api/v0/projects/source/new with a new source that has an invalid url """
toml_source = open ( " ./tests/pylorax/source/bad-repo.toml " ) . read ( )
self . assertTrue ( len ( toml_source ) > 0 )
resp = self . server . post ( " /api/v0/projects/source/new " ,
data = toml_source ,
content_type = " text/x-toml " )
2018-05-31 17:02:54 +00:00
self . assertEqual ( resp . status_code , 400 )
2018-05-30 22:13:02 +00:00
data = json . loads ( resp . data )
self . assertEqual ( data [ " status " ] , False )
2018-05-29 19:22:34 +00:00
def test_projects_source_01_delete_system ( self ) :
""" Test /api/v0/projects/source/delete a system source """
2018-07-26 22:06:05 +00:00
resp = self . server . delete ( " /api/v0/projects/source/delete/ " + self . system_repo )
2018-05-31 17:02:54 +00:00
self . assertEqual ( resp . status_code , 400 )
2018-05-29 19:22:34 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " status " ] , False )
# Make sure base is still listed
resp = self . server . get ( " /api/v0/projects/source/list " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-07-27 22:47:22 +00:00
self . assertTrue ( self . system_repo in data [ " sources " ] , " %s not in %s " % ( self . system_repo , data [ " sources " ] ) )
2018-05-29 19:22:34 +00:00
def test_projects_source_02_delete_single ( self ) :
""" Test /api/v0/projects/source/delete a single source """
resp = self . server . delete ( " /api/v0/projects/source/delete/single-repo " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data , { " status " : True } )
# Make sure single-repo isn't listed
resp = self . server . get ( " /api/v0/projects/source/list " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertTrue ( " single-repo " not in data [ " sources " ] )
def test_projects_source_03_delete_unknown ( self ) :
""" Test /api/v0/projects/source/delete an unknown source """
resp = self . server . delete ( " /api/v0/projects/source/delete/unknown-repo " )
2018-05-31 17:02:54 +00:00
self . assertEqual ( resp . status_code , 400 )
2018-05-29 19:22:34 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " status " ] , False )
def test_projects_source_04_delete_multi ( self ) :
""" Test /api/v0/projects/source/delete a source from a file with multiple sources """
resp = self . server . delete ( " /api/v0/projects/source/delete/lorax-3 " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data , { " status " : True } )
# Make sure single-repo isn't listed
resp = self . server . get ( " /api/v0/projects/source/list " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertTrue ( " lorax-3 " not in data [ " sources " ] )
2017-11-22 18:29:33 +00:00
def test_modules_list ( self ) :
""" Test /api/v0/modules/list """
resp = self . server . get ( " /api/v0/modules/list " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
modules = data . get ( " modules " )
self . assertEqual ( len ( modules ) > 10 , True )
self . assertEqual ( modules [ 0 ] [ " group_type " ] , " rpm " )
2017-11-22 23:31:21 +00:00
resp = self . server . get ( " /api/v0/modules/list/d* " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
modules = data . get ( " modules " )
self . assertEqual ( len ( modules ) > 0 , True )
self . assertEqual ( modules [ 0 ] [ " name " ] . startswith ( " d " ) , True )
2017-11-22 18:29:33 +00:00
def test_modules_info ( self ) :
""" Test /api/v0/modules/info """
resp = self . server . get ( " /api/v0/modules/info/bash " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
modules = data . get ( " modules " )
self . assertEqual ( len ( modules ) , 1 )
self . assertEqual ( modules [ 0 ] [ " name " ] , " bash " )
2018-07-11 18:07:45 +00:00
self . assertTrue ( " basesystem " in [ dep [ " name " ] for dep in modules [ 0 ] [ " dependencies " ] ] )
2017-12-21 17:44:59 +00:00
2018-03-28 19:40:10 +00:00
def test_blueprint_new_branch ( self ) :
2018-03-27 23:42:36 +00:00
""" Test the /api/v0/blueprints/new route with a new branch """
2018-03-28 19:40:10 +00:00
test_blueprint = { " description " : " An example GlusterFS server with samba " ,
2017-12-21 17:44:59 +00:00
" name " : " glusterfs " ,
" version " : " 0.2.0 " ,
2018-07-26 22:06:05 +00:00
" modules " : [ { " name " : " glusterfs " , " version " : " 3.*.* " } ,
{ " name " : " glusterfs-cli " , " version " : " 3.*.* " } ] ,
" packages " : [ { " name " : " samba " , " version " : " 4.*.* " } ,
2018-07-11 18:07:45 +00:00
{ " name " : " tmux " , " version " : " 1.8 " } ] ,
" groups " : [ ] }
2017-12-21 17:44:59 +00:00
2018-03-27 23:42:36 +00:00
resp = self . server . post ( " /api/v0/blueprints/new?branch=test " ,
2018-03-28 19:40:10 +00:00
data = json . dumps ( test_blueprint ) ,
2017-12-21 17:44:59 +00:00
content_type = " application/json " )
data = json . loads ( resp . data )
self . assertEqual ( data , { " status " : True } )
2018-03-27 23:42:36 +00:00
resp = self . server . get ( " /api/v0/blueprints/info/glusterfs?branch=test " )
2017-12-21 17:44:59 +00:00
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-03-28 19:40:10 +00:00
blueprints = data . get ( " blueprints " )
self . assertEqual ( len ( blueprints ) , 1 )
self . assertEqual ( blueprints [ 0 ] , test_blueprint )
2018-02-12 14:56:24 +00:00
2018-02-16 09:07:51 +00:00
def assert_documentation ( self , response ) :
"""
Assert response containing documentation from / api / doc / is
valid * without * comparing to the actual file on disk .
"""
self . assertEqual ( 200 , response . status_code )
self . assertTrue ( len ( response . data ) > 1024 )
# look for some well known strings inside the documentation
2018-03-23 00:25:00 +00:00
self . assertRegexpMatches ( response . data , r " Lorax [ \ d.]+ documentation " )
self . assertRegexpMatches ( response . data , r " Copyright \ d+, Red Hat, Inc. " )
2018-02-16 09:07:51 +00:00
2018-02-12 14:56:24 +00:00
def test_api_docs ( self ) :
""" Test the /api/docs/ """
resp = self . server . get ( " /api/docs/ " )
2018-02-16 09:07:51 +00:00
self . assert_documentation ( resp )
2018-02-12 14:56:24 +00:00
def test_api_docs_with_existing_path ( self ) :
""" Test the /api/docs/modules.html """
resp = self . server . get ( " /api/docs/modules.html " )
2018-02-16 09:07:51 +00:00
self . assert_documentation ( resp )
2018-02-10 01:39:42 +00:00
def wait_for_status ( self , uuid , wait_status ) :
""" Helper function that waits for a status
: param uuid : UUID of the build to check
: type uuid : str
: param wait_status : List of statuses to exit on
: type wait_status : list of str
: returns : True if status was found , False if it timed out
: rtype : bool
This will time out after 60 seconds
"""
start = time . time ( )
while True :
resp = self . server . get ( " /api/v0/compose/info/ %s " % uuid )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
queue_status = data . get ( " queue_status " )
if queue_status in wait_status :
return True
if time . time ( ) > start + 60 :
return False
2018-05-29 19:22:34 +00:00
time . sleep ( 1 )
2018-02-10 01:39:42 +00:00
def test_compose_01_types ( self ) :
""" Test the /api/v0/compose/types route """
resp = self . server . get ( " /api/v0/compose/types " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( { " name " : " tar " , " enabled " : True } in data [ " types " ] , True )
2018-04-23 22:59:26 +00:00
def test_compose_02_bad_type ( self ) :
""" Test that using an unsupported image type failes """
test_compose = { " blueprint_name " : " glusterfs " ,
" compose_type " : " snakes " ,
" branch " : " master " }
resp = self . server . post ( " /api/v0/compose?test=1 " ,
data = json . dumps ( test_compose ) ,
content_type = " application/json " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " status " ] , False , " Failed to fail to start test compose: %s " % data )
2018-08-09 14:21:21 +00:00
self . assertEqual ( data [ " errors " ] , [ { " id " : BAD_COMPOSE_TYPE , " msg " : " Invalid compose type (snakes), must be one of [ ' ext4-filesystem ' , ' live-iso ' , ' partitioned-disk ' , ' qcow2 ' , ' tar ' ] " } ] ,
2018-04-23 22:59:26 +00:00
" Failed to get errors: %s " % data )
def test_compose_03_status_fail ( self ) :
""" Test that requesting a status for a bad uuid is empty """
resp = self . server . get ( " /api/v0/compose/status/NO-UUID-TO-SEE-HERE " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " uuids " ] , [ ] , " Failed to get empty result bad uuid: %s " % data )
def test_compose_04_cancel_fail ( self ) :
""" Test that requesting a cancel for a bad uuid fails. """
resp = self . server . delete ( " /api/v0/compose/cancel/NO-UUID-TO-SEE-HERE " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " status " ] , False , " Failed to get an error for a bad uuid: %s " % data )
2018-08-08 14:57:46 +00:00
self . assertEqual ( data [ " errors " ] , [ { " id " : UNKNOWN_UUID , " msg " : " NO-UUID-TO-SEE-HERE is not a valid build uuid " } ] ,
" Failed to get errors: %s " % data )
2018-04-23 22:59:26 +00:00
def test_compose_05_delete_fail ( self ) :
""" Test that requesting a delete for a bad uuid fails. """
resp = self . server . delete ( " /api/v0/compose/delete/NO-UUID-TO-SEE-HERE " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
2018-08-08 14:57:46 +00:00
self . assertEqual ( data [ " errors " ] , [ { " id " : UNKNOWN_UUID , " msg " : " no-uuid-to-see-here is not a valid build uuid " } ] ,
2018-04-23 22:59:26 +00:00
" Failed to get an error for a bad uuid: %s " % data )
def test_compose_06_info_fail ( self ) :
""" Test that requesting info for a bad uuid fails. """
resp = self . server . get ( " /api/v0/compose/info/NO-UUID-TO-SEE-HERE " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " status " ] , False , " Failed to get an error for a bad uuid: %s " % data )
2018-08-08 14:57:46 +00:00
self . assertEqual ( data [ " errors " ] , [ { " id " : UNKNOWN_UUID , " msg " : " NO-UUID-TO-SEE-HERE is not a valid build uuid " } ] ,
2018-04-23 22:59:26 +00:00
" Failed to get errors: %s " % data )
def test_compose_07_metadata_fail ( self ) :
""" Test that requesting metadata for a bad uuid fails. """
resp = self . server . get ( " /api/v0/compose/metadata/NO-UUID-TO-SEE-HERE " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " status " ] , False , " Failed to get an error for a bad uuid: %s " % data )
2018-08-08 14:57:46 +00:00
self . assertEqual ( data [ " errors " ] , [ { " id " : UNKNOWN_UUID , " msg " : " NO-UUID-TO-SEE-HERE is not a valid build uuid " } ] ,
2018-04-23 22:59:26 +00:00
" Failed to get errors: %s " % data )
def test_compose_08_results_fail ( self ) :
""" Test that requesting results for a bad uuid fails. """
resp = self . server . get ( " /api/v0/compose/results/NO-UUID-TO-SEE-HERE " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " status " ] , False , " Failed to get an error for a bad uuid: %s " % data )
2018-08-08 14:57:46 +00:00
self . assertEqual ( data [ " errors " ] , [ { " id " : UNKNOWN_UUID , " msg " : " NO-UUID-TO-SEE-HERE is not a valid build uuid " } ] ,
" Failed to get errors: %s " % data )
2018-04-23 22:59:26 +00:00
def test_compose_09_logs_fail ( self ) :
""" Test that requesting logs for a bad uuid fails. """
resp = self . server . get ( " /api/v0/compose/logs/NO-UUID-TO-SEE-HERE " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " status " ] , False , " Failed to get an error for a bad uuid: %s " % data )
2018-08-08 14:57:46 +00:00
self . assertEqual ( data [ " errors " ] , [ { " id " : UNKNOWN_UUID , " msg " : " NO-UUID-TO-SEE-HERE is not a valid build uuid " } ] ,
2018-04-23 22:59:26 +00:00
" Failed to get errors: %s " % data )
def test_compose_10_log_fail ( self ) :
""" Test that requesting log for a bad uuid fails. """
resp = self . server . get ( " /api/v0/compose/log/NO-UUID-TO-SEE-HERE " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " status " ] , False , " Failed to get an error for a bad uuid: %s " % data )
2018-08-08 14:57:46 +00:00
self . assertEqual ( data [ " errors " ] , [ { " id " : UNKNOWN_UUID , " msg " : " NO-UUID-TO-SEE-HERE is not a valid build uuid " } ] ,
2018-04-23 22:59:26 +00:00
" Failed to get errors: %s " % data )
def test_compose_11_create_failed ( self ) :
2018-02-10 01:39:42 +00:00
""" Test the /api/v0/compose routes with a failed test compose """
2018-03-28 19:40:10 +00:00
test_compose = { " blueprint_name " : " glusterfs " ,
2018-02-10 01:39:42 +00:00
" compose_type " : " tar " ,
" branch " : " master " }
resp = self . server . post ( " /api/v0/compose?test=1 " ,
data = json . dumps ( test_compose ) ,
content_type = " application/json " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " status " ] , True , " Failed to start test compose: %s " % data )
build_id = data [ " build_id " ]
# Is it in the queue list (either new or run is fine, based on timing)
resp = self . server . get ( " /api/v0/compose/queue " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
ids = [ e [ " id " ] for e in data [ " new " ] + data [ " run " ] ]
self . assertEqual ( build_id in ids , True , " Failed to add build to the queue " )
# Wait for it to start
self . assertEqual ( self . wait_for_status ( build_id , [ " RUNNING " ] ) , True , " Failed to start test compose " )
# Wait for it to finish
self . assertEqual ( self . wait_for_status ( build_id , [ " FAILED " ] ) , True , " Failed to finish test compose " )
resp = self . server . get ( " /api/v0/compose/info/ %s " % build_id )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " queue_status " ] , " FAILED " , " Build not in FAILED state " )
# Test the /api/v0/compose/failed route
resp = self . server . get ( " /api/v0/compose/failed " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
ids = [ e [ " id " ] for e in data [ " failed " ] ]
self . assertEqual ( build_id in ids , True , " Failed build not listed by /compose/failed " )
# Test the /api/v0/compose/finished route
resp = self . server . get ( " /api/v0/compose/finished " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " finished " ] , [ ] , " Finished build not listed by /compose/finished " )
# Test the /api/v0/compose/status/<uuid> route
resp = self . server . get ( " /api/v0/compose/status/ %s " % build_id )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
ids = [ ( e [ " id " ] , e [ " queue_status " ] ) for e in data [ " uuids " ] ]
self . assertEqual ( ( build_id , " FAILED " ) in ids , True , " Failed build not listed by /compose/status " )
# Test the /api/v0/compose/cancel/<uuid> route
resp = self . server . post ( " /api/v0/compose?test=1 " ,
data = json . dumps ( test_compose ) ,
content_type = " application/json " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " status " ] , True , " Failed to start test compose: %s " % data )
cancel_id = data [ " build_id " ]
# Wait for it to start
self . assertEqual ( self . wait_for_status ( cancel_id , [ " RUNNING " ] ) , True , " Failed to start test compose " )
# Cancel the build
resp = self . server . delete ( " /api/v0/compose/cancel/ %s " % cancel_id )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " status " ] , True , " Failed to cancel test compose: %s " % data )
# Delete the failed build
# Test the /api/v0/compose/delete/<uuid> route
resp = self . server . delete ( " /api/v0/compose/delete/ %s " % build_id )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
ids = [ ( e [ " uuid " ] , e [ " status " ] ) for e in data [ " uuids " ] ]
self . assertEqual ( ( build_id , True ) in ids , True , " Failed to delete test compose: %s " % data )
# Make sure the failed list is empty
resp = self . server . get ( " /api/v0/compose/failed " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " failed " ] , [ ] , " Failed to delete the failed build: %s " % data )
2018-04-23 22:59:26 +00:00
def test_compose_12_create_finished ( self ) :
2018-02-10 01:39:42 +00:00
""" Test the /api/v0/compose routes with a finished test compose """
2018-05-08 16:25:44 +00:00
test_compose = { " blueprint_name " : " custom-base " ,
2018-02-10 01:39:42 +00:00
" compose_type " : " tar " ,
" branch " : " master " }
resp = self . server . post ( " /api/v0/compose?test=2 " ,
data = json . dumps ( test_compose ) ,
content_type = " application/json " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " status " ] , True , " Failed to start test compose: %s " % data )
build_id = data [ " build_id " ]
# Is it in the queue list (either new or run is fine, based on timing)
resp = self . server . get ( " /api/v0/compose/queue " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
ids = [ e [ " id " ] for e in data [ " new " ] + data [ " run " ] ]
self . assertEqual ( build_id in ids , True , " Failed to add build to the queue " )
# Wait for it to start
self . assertEqual ( self . wait_for_status ( build_id , [ " RUNNING " ] ) , True , " Failed to start test compose " )
# Wait for it to finish
self . assertEqual ( self . wait_for_status ( build_id , [ " FINISHED " ] ) , True , " Failed to finish test compose " )
resp = self . server . get ( " /api/v0/compose/info/ %s " % build_id )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " queue_status " ] , " FINISHED " , " Build not in FINISHED state " )
# Test the /api/v0/compose/finished route
resp = self . server . get ( " /api/v0/compose/finished " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
ids = [ e [ " id " ] for e in data [ " finished " ] ]
self . assertEqual ( build_id in ids , True , " Finished build not listed by /compose/finished " )
# Test the /api/v0/compose/failed route
resp = self . server . get ( " /api/v0/compose/failed " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " failed " ] , [ ] , " Failed build not listed by /compose/failed " )
# Test the /api/v0/compose/status/<uuid> route
resp = self . server . get ( " /api/v0/compose/status/ %s " % build_id )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
ids = [ ( e [ " id " ] , e [ " queue_status " ] ) for e in data [ " uuids " ] ]
self . assertEqual ( ( build_id , " FINISHED " ) in ids , True , " Finished build not listed by /compose/status " )
# Test the /api/v0/compose/metadata/<uuid> route
resp = self . server . get ( " /api/v0/compose/metadata/ %s " % build_id )
self . assertEqual ( resp . status_code , 200 )
self . assertEqual ( len ( resp . data ) > 1024 , True )
# Test the /api/v0/compose/results/<uuid> route
resp = self . server . get ( " /api/v0/compose/results/ %s " % build_id )
self . assertEqual ( resp . status_code , 200 )
self . assertEqual ( len ( resp . data ) > 1024 , True )
# Test the /api/v0/compose/image/<uuid> route
resp = self . server . get ( " /api/v0/compose/image/ %s " % build_id )
self . assertEqual ( resp . status_code , 200 )
self . assertEqual ( len ( resp . data ) > 0 , True )
self . assertEqual ( resp . data , " TEST IMAGE " )
2018-05-08 16:25:44 +00:00
# Examine the final-kickstart.ks for the customizations
# A bit kludgy since it examines the filesystem directly, but that's better than unpacking the metadata
final_ks = open ( joinpaths ( self . repo_dir , " var/lib/lorax/composer/results/ " , build_id , " final-kickstart.ks " ) ) . read ( )
# Check for the expected customizations in the kickstart
self . assertTrue ( " network --hostname= " in final_ks )
self . assertTrue ( " sshkey --user root " in final_ks )
2018-02-10 01:39:42 +00:00
# Delete the finished build
# Test the /api/v0/compose/delete/<uuid> route
resp = self . server . delete ( " /api/v0/compose/delete/ %s " % build_id )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
ids = [ ( e [ " uuid " ] , e [ " status " ] ) for e in data [ " uuids " ] ]
self . assertEqual ( ( build_id , True ) in ids , True , " Failed to delete test compose: %s " % data )
# Make sure the finished list is empty
resp = self . server . get ( " /api/v0/compose/finished " )
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( data [ " finished " ] , [ ] , " Failed to delete the failed build: %s " % data )
2018-08-06 19:31:52 +00:00
def assertInputError ( self , resp ) :
""" Check all the conditions for a successful input check error result """
data = json . loads ( resp . data )
self . assertNotEqual ( data , None )
self . assertEqual ( resp . status_code , 400 )
self . assertEqual ( data [ " status " ] , False )
2018-08-06 21:21:24 +00:00
self . assertTrue ( len ( data [ " errors " ] ) > 0 )
self . assertTrue ( " Invalid characters in " in data [ " errors " ] [ 0 ] )
def test_blueprints_list_branch ( self ) :
resp = self . server . get ( " /api/v0/blueprints/list?branch= " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 19:31:52 +00:00
def test_blueprints_info_input ( self ) :
""" Test the blueprints/info input character checking """
# /api/v0/blueprints/info/<blueprint_names>
resp = self . server . get ( " /api/v0/blueprints/info/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 21:21:24 +00:00
resp = self . server . get ( " /api/v0/blueprints/info/http-server?branch= " + UTF8_TEST_STRING )
self . assertInputError ( resp )
resp = self . server . get ( " /api/v0/blueprints/info/http-server?format= " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 19:31:52 +00:00
def test_blueprints_changes_input ( self ) :
""" Test the blueprints/changes input character checking """
# /api/v0/blueprints/changes/<blueprint_names>
resp = self . server . get ( " /api/v0/blueprints/changes/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 21:21:24 +00:00
resp = self . server . get ( " /api/v0/blueprints/changes/http-server?branch= " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 19:31:52 +00:00
def test_blueprints_new_input ( self ) :
""" Test the blueprints/new input character checking """
# /api/v0/blueprints/new
test_blueprint = { " description " : " An example GlusterFS server with samba " ,
" name " : UTF8_TEST_STRING ,
" version " : " 0.2.0 " ,
" modules " : [ { " name " : " glusterfs " , " version " : " 3.*.* " } ,
{ " name " : " glusterfs-cli " , " version " : " 3.*.* " } ] ,
" packages " : [ { " name " : " samba " , " version " : " 4.*.* " } ,
{ " name " : " tmux " , " version " : " 1.8 " } ] ,
" groups " : [ ] }
resp = self . server . post ( " /api/v0/blueprints/new " ,
data = json . dumps ( test_blueprint ) ,
content_type = " application/json " )
self . assertInputError ( resp )
2018-08-06 21:21:24 +00:00
test_blueprint [ " name " ] = " glusterfs "
resp = self . server . post ( " /api/v0/blueprints/new?branch= " + UTF8_TEST_STRING ,
data = json . dumps ( test_blueprint ) ,
content_type = " application/json " )
self . assertInputError ( resp )
2018-08-06 19:31:52 +00:00
def test_blueprints_delete_input ( self ) :
""" Test the blueprints/delete input character checking """
resp = self . server . delete ( " /api/v0/blueprints/delete/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 21:21:24 +00:00
resp = self . server . delete ( " /api/v0/blueprints/delete/http-server?branch= " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 19:31:52 +00:00
def test_blueprints_workspace_input ( self ) :
""" Test the blueprints/workspace input character checking """
test_blueprint = { " description " : " An example GlusterFS server with samba, ws version " ,
" name " : UTF8_TEST_STRING ,
" version " : " 0.3.0 " ,
" modules " : [ { " name " : " glusterfs " , " version " : " 3.*.* " } ,
{ " name " : " glusterfs-cli " , " version " : " 3.*.* " } ] ,
" packages " : [ { " name " : " samba " , " version " : " 4.*.* " } ,
{ " name " : " tmux " , " version " : " 1.8 " } ] ,
" groups " : [ ] }
resp = self . server . post ( " /api/v0/blueprints/workspace " ,
data = json . dumps ( test_blueprint ) ,
content_type = " application/json " )
self . assertInputError ( resp )
2018-08-06 21:21:24 +00:00
test_blueprint [ " name " ] = " glusterfs "
resp = self . server . post ( " /api/v0/blueprints/workspace?branch= " + UTF8_TEST_STRING ,
data = json . dumps ( test_blueprint ) ,
content_type = " application/json " )
self . assertInputError ( resp )
2018-08-06 19:31:52 +00:00
def test_blueprints_workspace_delete_input ( self ) :
""" Test the DELETE blueprints/workspace input character checking """
resp = self . server . delete ( " /api/v0/blueprints/workspace/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 21:21:24 +00:00
resp = self . server . delete ( " /api/v0/blueprints/workspace/http-server?branch= " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 19:31:52 +00:00
def test_blueprints_undo_input ( self ) :
""" Test the blueprints/undo/... input character checking """
resp = self . server . post ( " /api/v0/blueprints/undo/ " + UTF8_TEST_STRING + " /deadbeef " )
self . assertInputError ( resp )
2018-08-06 21:21:24 +00:00
resp = self . server . post ( " /api/v0/blueprints/undo/http-server/deadbeef?branch= " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 19:31:52 +00:00
def test_blueprints_tag_input ( self ) :
""" Test the blueprints/tag input character checking """
resp = self . server . post ( " /api/v0/blueprints/tag/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 21:21:24 +00:00
resp = self . server . post ( " /api/v0/blueprints/tag/http-server?branch= " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 19:31:52 +00:00
def test_blueprints_diff_input ( self ) :
""" Test the blueprints/diff input character checking """
# /api/v0/blueprints/diff/<blueprint_name>/<from_commit>/<to_commit>
resp = self . server . get ( " /api/v0/blueprints/diff/ " + UTF8_TEST_STRING + " /NEWEST/WORKSPACE " )
self . assertInputError ( resp )
2018-08-06 21:21:24 +00:00
resp = self . server . get ( " /api/v0/blueprints/diff/http-server/NEWEST/WORKSPACE?branch= " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 19:31:52 +00:00
def test_blueprints_freeze_input ( self ) :
""" Test the blueprints/freeze input character checking """
resp = self . server . get ( " /api/v0/blueprints/freeze/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 21:21:24 +00:00
resp = self . server . get ( " /api/v0/blueprints/freeze/http-server?branch= " + UTF8_TEST_STRING )
self . assertInputError ( resp )
resp = self . server . get ( " /api/v0/blueprints/freeze/http-server?format= " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 19:31:52 +00:00
def test_blueprints_depsolve_input ( self ) :
""" Test the blueprints/depsolve input character checking """
resp = self . server . get ( " /api/v0/blueprints/depsolve/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 21:21:24 +00:00
resp = self . server . get ( " /api/v0/blueprints/depsolve/http-server?branch= " + UTF8_TEST_STRING )
self . assertInputError ( resp )
2018-08-06 19:31:52 +00:00
def test_projects_info_input ( self ) :
""" Test the projects/info input character checking """
resp = self . server . get ( " /api/v0/projects/info/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_projects_depsolve_input ( self ) :
""" Test the projects/depsolve input character checking """
resp = self . server . get ( " /api/v0/projects/depsolve/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_projects_source_info_input ( self ) :
""" Test the projects/source/info input character checking """
resp = self . server . get ( " /api/v0/projects/source/info/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_projects_source_delete_input ( self ) :
""" Test the projects/source/delete input character checking """
resp = self . server . delete ( " /api/v0/projects/source/delete/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_modules_list_input ( self ) :
""" Test the modules/list input character checking """
resp = self . server . get ( " /api/v0/modules/list/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_modules_info_input ( self ) :
""" Test the modules/info input character checking """
resp = self . server . get ( " /api/v0/modules/info/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_compose_status_input ( self ) :
""" Test the compose/status input character checking """
resp = self . server . get ( " /api/v0/compose/status/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_compose_cancel_input ( self ) :
""" Test the compose/cancel input character checking """
resp = self . server . delete ( " /api/v0/compose/cancel/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_compose_delete_input ( self ) :
""" Test the compose/delete input character checking """
resp = self . server . delete ( " /api/v0/compose/delete/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_compose_info_input ( self ) :
""" Test the compose/info input character checking """
resp = self . server . get ( " /api/v0/compose/info/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_compose_metadata_input ( self ) :
""" Test the compose/metadata input character checking """
resp = self . server . get ( " /api/v0/compose/metadata/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_compose_results_input ( self ) :
""" Test the compose/results input character checking """
resp = self . server . get ( " /api/v0/compose/results/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_compose_logs_input ( self ) :
""" Test the compose/logs input character checking """
resp = self . server . get ( " /api/v0/compose/logs/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_compose_image_input ( self ) :
""" Test the compose/image input character checking """
resp = self . server . get ( " /api/v0/compose/image/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )
def test_compose_log_input ( self ) :
""" Test the compose/log input character checking """
resp = self . server . get ( " /api/v0/compose/log/ " + UTF8_TEST_STRING )
self . assertInputError ( resp )