2018-05-04 18:35:31 +00:00
#
# Copyright (C) 2018 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-07-27 01:10:57 +00:00
import os
2020-10-06 22:40:44 +00:00
import tempfile
2018-05-04 18:35:31 +00:00
import unittest
2018-07-27 01:10:57 +00:00
from . . lib import captured_output
2019-05-24 21:43:15 +00:00
from composer . cli . blueprints import pretty_diff_entry , blueprints_list , blueprints_show , blueprints_changes
2018-07-27 01:10:57 +00:00
from composer . cli . blueprints import blueprints_diff , blueprints_save , blueprints_delete , blueprints_depsolve
from composer . cli . blueprints import blueprints_push , blueprints_freeze , blueprints_undo , blueprints_tag
2019-05-24 21:43:15 +00:00
from composer . cli . blueprints import pretty_dict , dict_names
2018-05-04 18:35:31 +00:00
diff_entries = [ { ' new ' : { ' Description ' : ' Shiny new description ' } , ' old ' : { ' Description ' : ' Old reliable description ' } } ,
{ ' new ' : { ' Version ' : ' 0.3.1 ' } , ' old ' : { ' Version ' : ' 0.1.1 ' } } ,
{ ' new ' : { ' Module ' : { ' name ' : ' openssh ' , ' version ' : ' 2.8.1 ' } } , ' old ' : None } ,
2019-02-19 00:55:36 +00:00
{ ' new ' : None , ' old ' : { ' Module ' : { ' name ' : ' bash ' , ' version ' : ' 5.* ' } } } ,
2018-05-04 18:35:31 +00:00
{ ' new ' : { ' Module ' : { ' name ' : ' httpd ' , ' version ' : ' 3.8.* ' } } ,
' old ' : { ' Module ' : { ' name ' : ' httpd ' , ' version ' : ' 3.7.* ' } } } ,
2019-05-24 21:43:15 +00:00
{ ' new ' : { ' Package ' : { ' name ' : ' git ' , ' version ' : ' 2.13.* ' } } , ' old ' : None } ,
# New items
{ " new " : { " Group " : { " name " : " core " } } , " old " : None } ,
{ " new " : { " Customizations.firewall " : { " ports " : [ " 8888:tcp " , " 22:tcp " , " dns:udp " , " 9090:tcp " ] , " services " : [ " smtp " ] } } , " old " : None } ,
{ " new " : { " Customizations.hostname " : " foobar " } , " old " : None } ,
{ " new " : { " Customizations.locale " : { " keyboard " : " US " } } , " old " : None } ,
{ " new " : { " Customizations.sshkey " : [ { " key " : " ssh-rsa AAAAB3NzaC1... norm@localhost.localdomain " , " user " : " norm " } ] } , " old " : None } ,
{ " new " : { " Customizations.timezone " : { " ntpservers " : [ " ntp.nowhere.com " ] , " timezone " : " PST8PDT " } } , " old " : None } ,
{ " new " : { " Customizations.user " : [ { " key " : " ssh-rsa AAAAB3NzaC1... root@localhost.localdomain " , " name " : " root " , " password " : " fobarfobar " } ] } , " old " : None } ,
{ " new " : { " Repos.git " : { " destination " : " /opt/server-1/ " , " ref " : " v1.0 " , " repo " : " PATH OF GIT REPO TO CLONE " , " rpmname " : " server-config " , " rpmrelease " : " 2 " , " rpmversion " : " 1.0 " , " summary " : " Setup files for server deployment " } } , " old " : None } ,
# Removed items (just reversed old/old from above block)
{ " old " : { " Group " : { " name " : " core " } } , " new " : None } ,
{ " old " : { " Customizations.firewall " : { " ports " : [ " 8888:tcp " , " 22:tcp " , " dns:udp " , " 9090:tcp " ] , " services " : [ " smtp " ] } } , " new " : None } ,
{ " old " : { " Customizations.hostname " : " foobar " } , " new " : None } ,
{ " old " : { " Customizations.locale " : { " keyboard " : " US " } } , " new " : None } ,
{ " old " : { " Customizations.sshkey " : [ { " key " : " ssh-rsa AAAAB3NzaC1... norm@localhost.localdomain " , " user " : " norm " } ] } , " new " : None } ,
{ " old " : { " Customizations.timezone " : { " ntpservers " : [ " ntp.nowhere.com " ] , " timezone " : " PST8PDT " } } , " new " : None } ,
{ " old " : { " Customizations.user " : [ { " key " : " ssh-rsa AAAAB3NzaC1... root@localhost.localdomain " , " name " : " root " , " password " : " fobarfobar " } ] } , " new " : None } ,
{ " old " : { " Repos.git " : { " destination " : " /opt/server-1/ " , " ref " : " v1.0 " , " repo " : " PATH OF GIT REPO TO CLONE " , " rpmname " : " server-config " , " rpmrelease " : " 2 " , " rpmversion " : " 1.0 " , " summary " : " Setup files for server deployment " } } , " new " : None } ,
# Changed items
{ " old " : { " Customizations.firewall " : { " ports " : [ " 8888:tcp " , " 22:tcp " , " dns:udp " , " 9090:tcp " ] , " services " : [ " smtp " ] } } , " new " : { " Customizations.firewall " : { " ports " : [ " 8888:tcp " , " 22:tcp " , " 25:tcp " ] } } } ,
{ " old " : { " Customizations.hostname " : " foobar " } , " new " : { " Customizations.hostname " : " grues " } } ,
{ " old " : { " Customizations.locale " : { " keyboard " : " US " } } , " new " : { " Customizations.locale " : { " keyboard " : " US " , " languages " : [ " en_US.UTF-8 " ] } } } ,
{ " old " : { " Customizations.sshkey " : [ { " key " : " ssh-rsa AAAAB3NzaC1... norm@localhost.localdomain " , " user " : " norm " } ] } , " new " : { " Customizations.sshkey " : [ { " key " : " ssh-rsa ABCDEF01234... norm@localhost.localdomain " , " user " : " norm " } ] } } ,
{ " old " : { " Customizations.timezone " : { " ntpservers " : [ " ntp.nowhere.com " ] , " timezone " : " PST8PDT " } } , " new " : { " Customizations.timezone " : { " timezone " : " Antarctica/Palmer " } } } ,
{ " old " : { " Customizations.user " : [ { " key " : " ssh-rsa AAAAB3NzaC1... root@localhost.localdomain " , " name " : " root " , " password " : " fobarfobar " } ] } , " new " : { " Customizations.user " : [ { " key " : " ssh-rsa AAAAB3NzaC1... root@localhost.localdomain " , " name " : " root " , " password " : " qweqweqwe " } ] } } ,
{ " old " : { " Repos.git " : { " destination " : " /opt/server-1/ " , " ref " : " v1.0 " , " repo " : " PATH OF GIT REPO TO CLONE " , " rpmname " : " server-config " , " rpmrelease " : " 2 " , " rpmversion " : " 1.0 " , " summary " : " Setup files for server deployment " } } , " new " : { " Repos.git " : { " destination " : " /opt/server-1/ " , " ref " : " v1.0 " , " repo " : " PATH OF GIT REPO TO CLONE " , " rpmname " : " server-config " , " rpmrelease " : " 1 " , " rpmversion " : " 1.1 " , " summary " : " Setup files for server deployment " } } }
]
2018-05-04 18:35:31 +00:00
diff_result = [
' Changed Description " Old reliable description " -> " Shiny new description " ' ,
' Changed Version 0.1.1 -> 0.3.1 ' ,
' Added Module openssh 2.8.1 ' ,
2019-02-19 00:55:36 +00:00
' Removed Module bash 5.* ' ,
2018-05-04 18:35:31 +00:00
' Changed Module httpd 3.7.* -> 3.8.* ' ,
2019-05-24 21:43:15 +00:00
' Added Package git 2.13.* ' ,
' Added Group core ' ,
' Added Customizations.firewall ports= " 8888:tcp, 22:tcp, dns:udp, 9090:tcp " services= " smtp " ' ,
' Added Customizations.hostname foobar ' ,
' Added Customizations.locale keyboard= " US " ' ,
' Added Customizations.sshkey norm ' ,
' Added Customizations.timezone ntpservers= " ntp.nowhere.com " timezone= " PST8PDT " ' ,
' Added Customizations.user root ' ,
' Added Repos.git destination= " /opt/server-1/ " ref= " v1.0 " repo= " PATH OF GIT REPO TO CLONE " rpmname= " server-config " rpmrelease= " 2 " rpmversion= " 1.0 " summary= " Setup files for server deployment " ' ,
' Removed Group core ' ,
' Removed Customizations.firewall ports= " 8888:tcp, 22:tcp, dns:udp, 9090:tcp " services= " smtp " ' ,
' Removed Customizations.hostname foobar ' ,
' Removed Customizations.locale keyboard= " US " ' ,
' Removed Customizations.sshkey norm ' ,
' Removed Customizations.timezone ntpservers= " ntp.nowhere.com " timezone= " PST8PDT " ' ,
' Removed Customizations.user root ' ,
' Removed Repos.git destination= " /opt/server-1/ " ref= " v1.0 " repo= " PATH OF GIT REPO TO CLONE " rpmname= " server-config " rpmrelease= " 2 " rpmversion= " 1.0 " summary= " Setup files for server deployment " ' ,
' Changed Customizations.firewall ports= " 8888:tcp, 22:tcp, dns:udp, 9090:tcp " services= " smtp " -> ports= " 8888:tcp, 22:tcp, 25:tcp " ' ,
' Changed Customizations.hostname foobar -> grues ' ,
' Changed Customizations.locale keyboard= " US " -> keyboard= " US " languages= " en_US.UTF-8 " ' ,
' Changed Customizations.sshkey norm -> norm ' ,
' Changed Customizations.timezone ntpservers= " ntp.nowhere.com " timezone= " PST8PDT " -> timezone= " Antarctica/Palmer " ' ,
' Changed Customizations.user root -> root ' ,
' Changed Repos.git destination= " /opt/server-1/ " ref= " v1.0 " repo= " PATH OF GIT REPO TO CLONE " rpmname= " server-config " rpmrelease= " 2 " rpmversion= " 1.0 " summary= " Setup files for server deployment " -> destination= " /opt/server-1/ " ref= " v1.0 " repo= " PATH OF GIT REPO TO CLONE " rpmname= " server-config " rpmrelease= " 1 " rpmversion= " 1.1 " summary= " Setup files for server deployment " ' ,
]
dict_entries = [ { " ports " : [ " 8888:tcp " , " 22:tcp " , " dns:udp " , " 9090:tcp " ] } ,
{ " ports " : [ " 8888:tcp " , " 22:tcp " , " dns:udp " , " 9090:tcp " ] , " services " : [ " smtp " ] } ,
{ " destination " : " /opt/server-1/ " , " ref " : " v1.0 " , " repo " : " PATH OF GIT REPO TO CLONE " , " rpmname " : " server-config " , " rpmrelease " : " 1 " , " rpmversion " : " 1.0 " , " summary " : " Setup files for server deployment " } ,
{ " foo " : [ " one " , " two " ] , " bar " : { " baz " : " three " } } ]
dict_results = [ ' ports= " 8888:tcp, 22:tcp, dns:udp, 9090:tcp " ' ,
' ports= " 8888:tcp, 22:tcp, dns:udp, 9090:tcp " services= " smtp " ' ,
' destination= " /opt/server-1/ " ref= " v1.0 " repo= " PATH OF GIT REPO TO CLONE " rpmname= " server-config " rpmrelease= " 1 " rpmversion= " 1.0 " summary= " Setup files for server deployment " ' ,
' foo= " one, two " ' ]
dict_name_entry1 = [ { " name " : " bart " , " home " : " Springfield " } ,
{ " name " : " lisa " , " instrument " : " Saxaphone " } ,
{ " name " : " homer " , " kids " : [ " bart " , " maggie " , " lisa " ] } ]
dict_name_results1 = " bart, lisa, homer "
dict_name_entry2 = [ { " user " : " root " , " password " : " qweqweqwe " } ,
{ " user " : " norm " , " password " : " b33r " } ,
{ " user " : " cliff " , " password " : " POSTMASTER " } ]
dict_name_results2 = " root, norm, cliff "
dict_name_entry3 = [ { " home " : " /root " , " key " : " skeleton " } ,
{ " home " : " /home/norm " , " key " : " SSH KEY " } ,
{ " home " : " /home/cliff " , " key " : " lost " } ]
dict_name_results3 = " /root, /home/norm, /home/cliff "
2018-05-04 18:35:31 +00:00
2020-10-06 22:40:44 +00:00
HTTP_BLUEPRINT = b """ name = " example-http-server "
description = " An example http server with PHP and MySQL support. "
version = " 0.0.1 "
[ [ packages ] ]
name = " httpd "
version = " * "
[ [ packages ] ]
name = " tmux "
version = " * "
[ [ packages ] ]
name = " openssh-server "
version = " * "
[ [ packages ] ]
name = " rsync "
version = " * "
[ [ modules ] ]
name = " php "
version = " * "
"""
DEV_BLUEPRINT = b """ name = " example-development "
description = " A general purpose development image "
[ [ packages ] ]
name = " cmake "
version = " * "
[ [ packages ] ]
name = " curl "
version = " * "
[ [ packages ] ]
name = " gcc "
version = " * "
[ [ packages ] ]
name = " gdb "
version = " * "
"""
2018-05-04 18:35:31 +00:00
class BlueprintsTest ( unittest . TestCase ) :
2019-05-24 21:43:15 +00:00
def test_pretty_diff_entry ( self ) :
2018-05-04 18:35:31 +00:00
""" Return a nice representation of a diff entry """
2019-05-24 21:43:15 +00:00
self . assertEqual ( [ pretty_diff_entry ( entry ) for entry in diff_entries ] , diff_result )
def test_pretty_dict ( self ) :
""" Return a human readable single line """
self . assertEqual ( [ pretty_dict ( entry ) for entry in dict_entries ] , dict_results )
def test_dict_names_users ( self ) :
""" Return a list of the name field of the list of dicts """
self . assertEqual ( dict_names ( dict_name_entry1 ) , dict_name_results1 )
def test_dict_names_sshkey ( self ) :
""" Return a list of the user field of the list of dicts """
self . assertEqual ( dict_names ( dict_name_entry2 ) , dict_name_results2 )
def test_dict_names_other ( self ) :
""" Return a list of the unknown field of the list of dicts """
self . assertEqual ( dict_names ( dict_name_entry3 ) , dict_name_results3 )
2018-07-27 01:10:57 +00:00
2020-10-06 22:40:44 +00:00
@unittest.skipUnless ( os . path . exists ( " /run/weldr/api.socket " ) , " Tests require a running API server " )
class ServerBlueprintsTest ( unittest . TestCase ) :
# MUST come first, tests push and installs required blueprints
def test_0000 ( self ) :
""" initialize server blueprints """
for blueprint in [ HTTP_BLUEPRINT , DEV_BLUEPRINT ] :
with tempfile . NamedTemporaryFile ( prefix = " composer.test. " ) as tf :
tf . write ( blueprint )
tf . file . close ( )
rc = blueprints_push ( " /run/weldr/api.socket " , 0 , [ tf . name ] , show_json = False )
self . assertTrue ( rc == 0 )
2018-07-27 01:10:57 +00:00
def test_list ( self ) :
""" blueprints list """
with captured_output ( ) as ( out , _ ) :
rc = blueprints_list ( " /run/weldr/api.socket " , 0 , [ ] , show_json = False )
output = out . getvalue ( ) . strip ( )
self . assertTrue ( rc == 0 )
2018-08-21 22:08:58 +00:00
self . assertTrue ( " example-http-server " in output )
2018-07-27 01:10:57 +00:00
def test_show ( self ) :
""" blueprints show """
with captured_output ( ) as ( out , _ ) :
2018-08-21 22:08:58 +00:00
blueprints_show ( " /run/weldr/api.socket " , 0 , [ " example-http-server " ] , show_json = False )
2018-07-27 01:10:57 +00:00
output = out . getvalue ( ) . strip ( )
2018-08-21 22:08:58 +00:00
self . assertTrue ( " example-http-server " in output )
2018-07-27 01:10:57 +00:00
self . assertTrue ( " [[packages]] " in output )
self . assertTrue ( " [[modules]] " in output )
def test_changes ( self ) :
""" blueprints changes """
with captured_output ( ) as ( out , _ ) :
2018-08-21 22:08:58 +00:00
rc = blueprints_changes ( " /run/weldr/api.socket " , 0 , [ " example-http-server " ] , show_json = False )
2018-07-27 01:10:57 +00:00
output = out . getvalue ( ) . strip ( )
self . assertTrue ( rc == 0 )
2018-08-21 22:08:58 +00:00
self . assertTrue ( " example-http-server " in output )
self . assertTrue ( " Recipe example-http-server, version 0.0.1 saved. " in output )
2018-07-27 01:10:57 +00:00
def test_save_0 ( self ) :
""" blueprints save """
2018-08-21 22:08:58 +00:00
blueprints_save ( " /run/weldr/api.socket " , 0 , [ " example-http-server " ] , show_json = False )
self . assertTrue ( os . path . exists ( " example-http-server.toml " ) )
2018-07-27 01:10:57 +00:00
def test_save_1 ( self ) :
""" blueprints push """
2018-08-21 22:08:58 +00:00
rc = blueprints_push ( " /run/weldr/api.socket " , 0 , [ " example-http-server.toml " ] , show_json = False )
2018-07-27 01:10:57 +00:00
self . assertTrue ( rc == 0 )
def test_delete ( self ) :
""" blueprints delete """
2018-08-21 22:08:58 +00:00
rc = blueprints_delete ( " /run/weldr/api.socket " , 0 , [ " example-development " ] , show_json = False )
2018-07-27 01:10:57 +00:00
self . assertTrue ( rc == 0 )
def test_depsolve ( self ) :
""" blueprints depsolve """
with captured_output ( ) as ( out , _ ) :
2018-08-21 22:08:58 +00:00
rc = blueprints_depsolve ( " /run/weldr/api.socket " , 0 , [ " example-http-server " ] , show_json = False )
2018-07-27 01:10:57 +00:00
output = out . getvalue ( ) . strip ( )
self . assertTrue ( rc == 0 )
2018-08-21 22:08:58 +00:00
self . assertTrue ( " blueprint: example-http-server v " in output )
2018-07-27 01:10:57 +00:00
self . assertTrue ( " httpd " in output )
def test_freeze_show ( self ) :
""" blueprints freeze show """
with captured_output ( ) as ( out , _ ) :
2018-08-21 22:08:58 +00:00
rc = blueprints_freeze ( " /run/weldr/api.socket " , 0 , [ " show " , " example-http-server " ] , show_json = False )
2018-07-27 01:10:57 +00:00
output = out . getvalue ( ) . strip ( )
self . assertTrue ( rc == 0 )
self . assertTrue ( " version " in output )
2018-08-21 22:08:58 +00:00
self . assertTrue ( " example-http-server " in output )
2018-07-27 01:10:57 +00:00
self . assertTrue ( " x86_64 " in output )
self . assertTrue ( " [[packages]] " in output )
self . assertTrue ( " [[modules]] " in output )
def test_freeze_save ( self ) :
""" blueprints freeze save """
2018-08-21 22:08:58 +00:00
rc = blueprints_freeze ( " /run/weldr/api.socket " , 0 , [ " save " , " example-http-server " ] , show_json = False )
2018-07-27 01:10:57 +00:00
self . assertTrue ( rc == 0 )
2018-08-21 22:08:58 +00:00
self . assertTrue ( os . path . exists ( " example-http-server.frozen.toml " ) )
2018-07-27 01:10:57 +00:00
def test_freeze ( self ) :
""" blueprints freeze """
with captured_output ( ) as ( out , _ ) :
2018-08-21 22:08:58 +00:00
rc = blueprints_freeze ( " /run/weldr/api.socket " , 0 , [ " example-http-server " ] , show_json = False )
2018-07-27 01:10:57 +00:00
output = out . getvalue ( ) . strip ( )
self . assertTrue ( rc == 0 )
2018-08-21 22:08:58 +00:00
self . assertTrue ( " blueprint: example-http-server v " in output )
2018-07-27 01:10:57 +00:00
self . assertTrue ( " httpd " in output )
self . assertTrue ( " x86_64 " in output )
def test_tag ( self ) :
""" blueprints tag """
2019-11-08 07:58:51 +00:00
rc = blueprints_tag ( " /run/weldr/api.socket " , 0 , [ " example-http-server " ] , show_json = False )
2018-07-27 01:10:57 +00:00
self . assertTrue ( rc == 0 )
def test_undo ( self ) :
""" blueprints undo """
# Get the oldest commit, it should be 2nd to last line
with captured_output ( ) as ( out , _ ) :
2018-08-21 22:08:58 +00:00
rc = blueprints_changes ( " /run/weldr/api.socket " , 0 , [ " example-http-server " ] , show_json = False )
2018-07-27 01:10:57 +00:00
output = out . getvalue ( ) . strip ( ) . splitlines ( )
first_commit = output [ - 2 ] . split ( ) [ 1 ]
with captured_output ( ) as ( out , _ ) :
2018-08-21 22:08:58 +00:00
rc = blueprints_undo ( " /run/weldr/api.socket " , 0 , [ " example-http-server " , first_commit , " HEAD " ] , show_json = False )
2018-07-27 01:10:57 +00:00
output = out . getvalue ( ) . strip ( )
self . assertTrue ( rc == 0 )
def test_workspace ( self ) :
""" blueprints workspace """
2018-08-21 22:08:58 +00:00
rc = blueprints_push ( " /run/weldr/api.socket " , 0 , [ " example-http-server.toml " ] , show_json = False )
2018-07-27 01:10:57 +00:00
self . assertTrue ( rc == 0 )
2018-08-23 23:17:33 +00:00
# XXX MUST COME LAST
# XXX which is what _z_ ensures
2020-10-06 22:40:44 +00:00
@unittest.expectedFailure
2018-08-23 23:17:33 +00:00
def test_z_diff ( self ) :
""" blueprints diff """
# Get the oldest commit, it should be 2nd to last line
with captured_output ( ) as ( out , _ ) :
rc = blueprints_changes ( " /run/weldr/api.socket " , 0 , [ " example-http-server " ] , show_json = False )
output = out . getvalue ( ) . strip ( ) . splitlines ( )
first_commit = output [ - 2 ] . split ( ) [ 1 ]
with captured_output ( ) as ( out , _ ) :
2020-10-06 22:40:44 +00:00
rc = blueprints_diff ( " /run/weldr/api.socket " , 0 , [ " example-http-server " , first_commit , " NEWEST " ] , show_json = False )
2018-08-23 23:17:33 +00:00
output = out . getvalue ( ) . strip ( )
self . assertTrue ( rc == 0 )
self . assertTrue ( " Changed Version " in output )