Edgewall Software

source: trunk/bitten/tests_slave/recipe.py @ 1001

Last change on this file since 1001 was 913, checked in by osimons, 13 years ago

Slave attachment support via <attach /> is totally redone to use multi-part form post instead of inlining it in the XML (ie. like a web file upload form). For larger binaries the previous inlining would effectively be an internal denial-of-service attack...

Closes #615.

  • Property svn:eol-style set to native
File size: 7.2 KB
CovLine 
1# -*- coding: utf-8 -*-
2#
3# Copyright (C) 2005-2007 Christopher Lenz <cmlenz@gmx.de>
4# Copyright (C) 2007-2010 Edgewall Software
5# All rights reserved.
6#
7# This software is licensed as described in the file COPYING, which
8# you should have received as part of this distribution. The terms
9# are also available at http://bitten.edgewall.org/wiki/License.
10
111import os
112import shutil
113import tempfile
114import unittest
15
116from bitten.build.config import Configuration
117from bitten.recipe import Context, Recipe, InvalidRecipeError
118from bitten.util import xmlio
19
20
221class ContextTestCase(unittest.TestCase):
22
123    def setUp(self):
424        self.basedir = os.path.realpath(tempfile.mkdtemp())
25
126    def tearDown(self):
427        shutil.rmtree(self.basedir)
28
129    def test_vars_basedir(self):
130        config = Configuration(properties={'foo.bar': 'baz'})
131        ctxt = Context('%s/${path}/${foo.bar}' % os.path.realpath('/foo'),
132                        config, {'path': 'bar'})
33
134        self.assertEquals(os.path.realpath('/foo/bar/baz'),
135                        os.path.realpath(ctxt.vars['basedir']))
136        if os.name == 'nt':
37            # Make sure paths are double-escaped
038            self.failUnless('\\\\' in ctxt.vars['basedir'])
39
140    def test_run_wrong_arg(self):
141        ctxt = Context(self.basedir)
142        try:
143            ctxt.run(1, 'http://bitten.edgewall.org/tools/sh', 'exec', {'foo':'bar'})
044            self.fail("InvalidRecipeError expected")
145        except InvalidRecipeError, e:
146            self.failUnless("Unsupported argument 'foo'" in str(e))
47
148    def test_attach_file_config(self):
49        # Verify output from attaching a file to a config
150        ctxt = Context(self.basedir, Configuration())
51
152        ctxt.attach(file_='config.txt', description='config config',
153                      resource='config')
154        self.assertEquals(1, len(ctxt.output))
155        self.assertEquals(Recipe.ATTACH, ctxt.output[0][0])
156        attach_xml = ctxt.output[0][3]
157        self.assertEquals('<file resource="config" '
158                          'description="config config" '
159                          'filename="config.txt"/>', str(attach_xml))
60
161    def test_attach_file_build(self):
62        # Verify output from attaching a file to a build
163        ctxt = Context(self.basedir, Configuration())
64
165        ctxt.attach(file_='build.txt', description='build build')
166        self.assertEquals(1, len(ctxt.output))
167        self.assertEquals(Recipe.ATTACH, ctxt.output[0][0])
168        attach_xml = ctxt.output[0][3]
169        self.assertEquals('<file resource="build" '
170                          'description="build build" '
171                          'filename="build.txt"/>', str(attach_xml))
72
273class RecipeTestCase(unittest.TestCase):
74
175    def setUp(self):
1376        self.basedir = os.path.realpath(tempfile.mkdtemp())
77
178    def tearDown(self):
1379        shutil.rmtree(self.basedir)
80
181    def test_empty_recipe(self):
182        xml = xmlio.parse('<build/>')
183        recipe = Recipe(xml, basedir=self.basedir)
184        self.assertEqual(self.basedir, recipe.ctxt.basedir)
185        steps = list(recipe)
186        self.assertEqual(0, len(steps))
87
188    def test_empty_step(self):
189        xml = xmlio.parse('<build>'
190                          ' <step id="foo" description="Bar"></step>'
191                          '</build>')
192        recipe = Recipe(xml, basedir=self.basedir)
193        steps = list(recipe)
194        self.assertEqual(1, len(steps))
195        self.assertEqual('foo', steps[0].id)
196        self.assertEqual('Bar', steps[0].description)
197        self.assertEqual('fail', steps[0].onerror)
98
199    def test_validate_bad_root(self):
1100        xml = xmlio.parse('<foo></foo>')
1101        recipe = Recipe(xml, basedir=self.basedir)
1102        self.assertRaises(InvalidRecipeError, recipe.validate)
103
1104    def test_validate_no_steps(self):
1105        xml = xmlio.parse('<build></build>')
1106        recipe = Recipe(xml, basedir=self.basedir)
1107        self.assertRaises(InvalidRecipeError, recipe.validate)
108
1109    def test_validate_child_not_step(self):
0110        xml = xmlio.parse('<build><foo/></build>')
0111        recipe = Recipe(xml, basedir=self.basedir)
0112        self.assertRaises(InvalidRecipeError, recipe.validate)
113
1114    def test_validate_child_not_step(self):
1115        xml = xmlio.parse('<build><foo/></build>')
1116        recipe = Recipe(xml, basedir=self.basedir)
1117        self.assertRaises(InvalidRecipeError, recipe.validate)
118
1119    def test_validate_step_without_id(self):
1120        xml = xmlio.parse('<build><step><cmd/></step></build>')
1121        recipe = Recipe(xml, basedir=self.basedir)
1122        self.assertRaises(InvalidRecipeError, recipe.validate)
123
1124    def test_validate_step_with_empty_id(self):
1125        xml = xmlio.parse('<build><step id=""><cmd/></step></build>')
1126        recipe = Recipe(xml, basedir=self.basedir)
1127        self.assertRaises(InvalidRecipeError, recipe.validate)
128
1129    def test_validate_step_without_commands(self):
1130        xml = xmlio.parse('<build><step id="test"/></build>')
1131        recipe = Recipe(xml, basedir=self.basedir)
1132        self.assertRaises(InvalidRecipeError, recipe.validate)
133
1134    def test_validate_step_with_command_children(self):
1135        xml = xmlio.parse('<build><step id="test">'
1136                          '<somecmd><child1/><child2/></somecmd>'
1137                          '</step></build>')
1138        recipe = Recipe(xml, basedir=self.basedir)
1139        self.assertRaises(InvalidRecipeError, recipe.validate)
140
1141    def test_validate_step_with_duplicate_id(self):
1142        xml = xmlio.parse('<build>'
1143                          '<step id="test"><somecmd></somecmd></step>'
1144                          '<step id="test"><othercmd></othercmd></step>'
1145                          '</build>')
1146        recipe = Recipe(xml, basedir=self.basedir)
1147        self.assertRaises(InvalidRecipeError, recipe.validate)
148
1149    def test_validate_successful(self):
1150        xml = xmlio.parse('<build>'
1151                          '<step id="foo"><somecmd></somecmd></step>'
1152                          '<step id="bar"><othercmd></othercmd></step>'
1153                          '</build>')
1154        recipe = Recipe(xml, basedir=self.basedir)
1155        recipe.validate()
156
1157    def test_onerror_defaults(self):
1158        xml = xmlio.parse('<build onerror="continue">'
1159                          ' <step id="foo" description="Bar"></step>'
1160                          '</build>')
1161        recipe = Recipe(xml, basedir=self.basedir)
1162        steps = list(recipe)
1163        self.assertEqual(1, len(steps))
1164        self.assertEqual('foo', steps[0].id)
1165        self.assertEqual('Bar', steps[0].description)
1166        self.assertEqual('continue', steps[0].onerror)
167
168
1169    def test_onerror_override(self):
1170        xml = xmlio.parse('<build onerror="ignore">'
1171                          ' <step id="foo" description="Bar" onerror="continue"></step>'
1172                          '</build>')
1173        recipe = Recipe(xml, basedir=self.basedir)
1174        steps = list(recipe)
1175        self.assertEqual(1, len(steps))
1176        self.assertEqual('foo', steps[0].id)
1177        self.assertEqual('Bar', steps[0].description)
1178        self.assertEqual('continue', steps[0].onerror)
179
180
1181def suite():
1182    suite = unittest.TestSuite()
1183    suite.addTest(unittest.makeSuite(ContextTestCase, 'test'))
1184    suite.addTest(unittest.makeSuite(RecipeTestCase, 'test'))
1185    return suite
186
1187if __name__ == '__main__':
0188    unittest.main(defaultTest='suite')
Note: See TracBrowser for help on using the repository browser.