class TestJenkinsPush(TestCase): def executeBobJenkinsCmd(self, arg): doJenkins(arg.split(' '), self.cwd) def tearDown(self): self.jenkinsMock.stop_mock_server() finalize() os.chdir(self.oldCwd) removePath(self.cwd) def setUp(self): self.oldCwd = os.getcwd() self.jenkinsMock = JenkinsMock() self.jenkinsMock.start_mock_server() self.jenkinsMock.getServerData() self.cwd = tempfile.mkdtemp() os.chdir(self.cwd) def testSimplePush(self): RECIPE = """ root: True checkoutSCM: - scm: git url: [email protected] branch: test checkoutScript: | TestCheckoutScript buildScript: | TestBuildScript packageScript: | TestPackageScript """ os.mkdir("recipes") with open(os.path.join("recipes", "test.yaml"), "w") as f: print(RECIPE, file=f) # do bob jenkins add self.executeBobJenkinsCmd( "add myTestJenkins http://localhost:{} -r test".format( self.jenkinsMock.getServerPort())) # throw away server data (but there shouldn't by any... assert (len(self.jenkinsMock.getServerData()) == 0) self.executeBobJenkinsCmd("push myTestJenkins -q") send = self.jenkinsMock.getServerData() assert (len(send) == 2) assert ('createItem?name=test' in send[0][0]) jobconfig = ElementTree.fromstring(send[0][1]) self.assertEqual(jobconfig.tag, 'project') # test GitSCM for scm in jobconfig.iter('scm'): if ('git' in scm.attrib.get('class')): assert ('*****@*****.**' in [url.text for url in scm.iter('url')]) for branch in scm.iter('branches'): assert ('refs/heads/test' in [name.text for name in branch.iter('name')]) found = False for cmd in jobconfig.iter('command'): if (('TestCheckoutScript' in cmd.text) and ('TestBuildScript' in cmd.text) and ('TestPackageScript' in cmd.text)): found = True self.assertEqual(found, True) self.assertEqual('/job/test/build', send[1][0]) self.executeBobJenkinsCmd("prune -q myTestJenkins") send = self.jenkinsMock.getServerData() assert (len(send) == 1) assert ('/job/test/doDelete' == send[0][0]) self.executeBobJenkinsCmd("rm myTestJenkins") assert (len(self.jenkinsMock.getServerData()) == 0) def testStableJobConfig(self): # This test generates the following jobs with it's dependencies: # --> app1 -> lib-a # root -|--> app2 -> lib-b # --> app3 -> lib-c # Afterwards the app* jobs are modified. In this case the lib-* jobs shouldn't # be modified or triggered. RECIPE_LIB = """ buildScript: echo 'hello bob' multiPackage: a: packageScript: '1' b: packageScript: '2' c: packageScript: '3' """ RECIPE_APP = """ depends: - {DEPENDS} buildScript: | {SCRIPT} """ ROOT_RECIPE = """ root: True depends: - app1 - app2 - app3 buildScript: | true """ os.mkdir("recipes") with open(os.path.join("recipes", "root.yaml"), "w") as f: print(ROOT_RECIPE, file=f) with open(os.path.join("recipes", "lib.yaml"), "w") as f: print(RECIPE_LIB, file=f) with open(os.path.join("recipes", "app1.yaml"), "w") as f: print(RECIPE_APP.format(SCRIPT='test', DEPENDS='lib-a'), file=f) with open(os.path.join("recipes", "app2.yaml"), "w") as f: print(RECIPE_APP.format(SCRIPT='test1', DEPENDS='lib-b'), file=f) with open(os.path.join("recipes", "app3.yaml"), "w") as f: print(RECIPE_APP.format(SCRIPT='test2', DEPENDS='lib-c'), file=f) # do bob jenkins add self.executeBobJenkinsCmd( "add myTestJenkins http://localhost:{} -r root".format( self.jenkinsMock.getServerPort())) # throw away server data (but there shouldn't by any... assert (len(self.jenkinsMock.getServerData()) == 0) self.executeBobJenkinsCmd("push -q myTestJenkins") send = self.jenkinsMock.getServerData() self.assertEqual(len(send), 10) # 5 jobs, create + schedule # bob will try to receive the old job config. Put it on the server... for data in send: created = re.match(r"/createItem\?name=(.*)$", data[0]) if created: self.jenkinsMock.addServerData( '/job/{}/config.xml'.format(created.group(1)), data[1]) if 'lib' in created.group(1): oldTestConfig = data[1] testrun = 0 while testrun < 3: testrun += 1 with open(os.path.join("recipes", "app{}.yaml".format(testrun)), "w") as f: print(RECIPE_APP.format(DEPENDS='lib-{}'.format( chr(ord('a') - 1 + testrun)), SCRIPT='test_' + str(testrun)), file=f) self.executeBobJenkinsCmd("push myTestJenkins -q") send = self.jenkinsMock.getServerData() # one of the app's were changed. # jenkins has to reconfigure the app and the root job but not the lib job configsChanged = 0 for data in send: if 'job' in data[0] and 'config.xml' in data[0]: configsChanged += 1 assert (configsChanged == 2) self.executeBobJenkinsCmd("prune -q myTestJenkins") send = self.jenkinsMock.getServerData() assert (len(send) == 5) # deleted 5 Jobs self.executeBobJenkinsCmd("rm myTestJenkins") assert (len(self.jenkinsMock.getServerData()) == 0)
class TestJenkinsSetOptions(TestCase): def executeBobJenkinsCmd(self, arg): doJenkins(arg.split(' '), self.cwd) def tearDown(self): self.jenkinsMock.stop_mock_server() finalize() os.chdir(self.oldCwd) removePath(self.cwd) def setUp(self): RECIPE = """ root: True checkoutSCM: - scm: git url: [email protected] branch: test buildScript: | echo 'build' packageScript: | echo 'package' """ self.oldCwd = os.getcwd() self.cwd = tempfile.mkdtemp() self.jenkinsMock = JenkinsMock() self.jenkinsMock.start_mock_server() self.jenkinsMock.getServerData() os.chdir(self.cwd) os.mkdir("recipes") with open(os.path.join("recipes", "test.yaml"), "w") as f: print(RECIPE, file=f) # do bob jenkins add self.executeBobJenkinsCmd( "add myTestJenkins http://localhost:{} -r test".format( self.jenkinsMock.getServerPort())) self.executeBobJenkinsCmd("push -q myTestJenkins") self.jenkinsMock.getServerData() def createComplexRecipes(self): ROOT = """ root: True depends: - dependency-one - dependency-two checkoutSCM: - scm: git url: [email protected]/root.git branch: test buildScript: | echo 'build' packageScript: | echo 'package' """ DEPENDENCYONE = """ depends: - dependency-two checkoutSCM: - scm: git url: [email protected]/dependency-one.git branch: test buildScript: | echo 'build' packageScript: | echo 'package' """ DEPENDENCYTWO = """ checkoutSCM: - scm: git url: [email protected]/dependency-two.git branch: test buildScript: | echo 'build' packageScript: | echo 'package' """ with open(os.path.join("recipes", "root.yaml"), "w") as f: print(ROOT, file=f) with open(os.path.join("recipes", "dependency-one.yaml"), "w") as f: print(DEPENDENCYONE, file=f) with open(os.path.join("recipes", "dependency-two.yaml"), "w") as f: print(DEPENDENCYTWO, file=f) self.executeBobJenkinsCmd( "add myTestJenkinsComplex http://localhost:{} -r root".format( self.jenkinsMock.getServerPort())) def testSetNode(self): self.executeBobJenkinsCmd("set-options -n testSlave myTestJenkins") self.executeBobJenkinsCmd("push -q myTestJenkins") send = self.jenkinsMock.getServerData() assert ('<assignedNode>testSlave</assignedNode>' in send[0][1].decode('utf-8')) def testUpDownload(self): DEFAULT = """ archive: backend: http url: "http://localhost:8001/upload" """ with open("default.yaml", "w") as f: print(DEFAULT, file=f) self.executeBobJenkinsCmd("set-options --download myTestJenkins") self.executeBobJenkinsCmd("push -q myTestJenkins") send = self.jenkinsMock.getServerData() assert ('BOB_DOWNLOAD_URL=http://localhost:8001/upload' in send[0][1].decode('utf-8')) self.executeBobJenkinsCmd( "set-options --reset --add-root test myTestJenkins") self.executeBobJenkinsCmd("push -q myTestJenkins") send = self.jenkinsMock.getServerData() assert ('BOB_DOWNLOAD_URL=http://localhost:8001/upload' not in send[0][1].decode('utf-8')) self.executeBobJenkinsCmd("set-options --upload myTestJenkins") self.executeBobJenkinsCmd("push -q myTestJenkins") send = self.jenkinsMock.getServerData() assert ('BOB_UPLOAD_URL=http://localhost:8001/upload' in send[0][1].decode('utf-8')) def testSetURL(self): self.newJenkinsMock = JenkinsMock() self.newJenkinsMock.start_mock_server() self.executeBobJenkinsCmd( "set-url myTestJenkins http://localhost:{}".format( self.newJenkinsMock.getServerPort())) self.executeBobJenkinsCmd("push -q myTestJenkins") send = self.jenkinsMock.getServerData() sendNew = self.newJenkinsMock.getServerData() assert (len(send) == 0) assert (len(sendNew) != 0) self.newJenkinsMock.stop_mock_server() def testSetGitShallowClone(self): self.executeBobJenkinsCmd( "set-options -o scm.git.shallow=42 myTestJenkins") self.executeBobJenkinsCmd("push -q myTestJenkins") send = self.jenkinsMock.getServerData() config = ElementTree.fromstring(send[0][1]) for clone in config.iter( 'hudson.plugins.git.extensions.impl.CloneOption'): found = 0 for a in clone.getiterator(): if a.tag == 'shallow': assert (a.text == 'true') found += 1 if a.tag == 'depth': assert (a.text == '42') found += 1 assert (found == 2) self.executeBobJenkinsCmd( "set-options -o scm.git.shallow=-1 myTestJenkins") with self.assertRaises(Exception) as c: self.executeBobJenkinsCmd("push -q myTestJenkins") assert (type(c.exception) == BuildError) def testSetGitTimeoutClone(self): self.executeBobJenkinsCmd( "set-options -o scm.git.timeout=42 myTestJenkins") self.executeBobJenkinsCmd("push -q myTestJenkins") send = self.jenkinsMock.getServerData() config = ElementTree.fromstring(send[0][1]) for clone in config.iter( 'hudson.plugins.git.extensions.impl.CloneOption'): found = 0 for a in clone.getiterator(): if a.tag == 'timeout': assert (a.text == '42') found += 1 assert (found == 1) self.executeBobJenkinsCmd( "set-options -o scm.git.timeout=-10 myTestJenkins") with self.assertRaises(Exception) as c: self.executeBobJenkinsCmd("push -q myTestJenkins") assert (type(c.exception) == BuildError) def testSetPrefix(self): self.executeBobJenkinsCmd("set-options -p abcde- myTestJenkins") self.executeBobJenkinsCmd("push -q myTestJenkins") send = self.jenkinsMock.getServerData() assert (send[0][0] == '/createItem?name=abcde-test') assert (send[1][0] == '/job/test/doDelete') assert (send[2][0] == '/job/abcde-test/build') def testDelRoot(self): self.executeBobJenkinsCmd("set-options --del-root test myTestJenkins") self.executeBobJenkinsCmd("push -q myTestJenkins") send = self.jenkinsMock.getServerData() assert (send[0][0] == '/job/test/doDelete') def testShortDescription(self): self.createComplexRecipes() self.executeBobJenkinsCmd( "set-options --shortdescription myTestJenkinsComplex") self.executeBobJenkinsCmd("push -q myTestJenkinsComplex") send = self.jenkinsMock.getServerData() result_set = set() try: for i in send: if i[0] == '/createItem?name=dependency-two': for items in ElementTree.fromstring( i[1]).iter('description'): for line in [x for x in items.itertext() ][0].splitlines(): if line.startswith('<li>') and line.endswith( '</li>'): result_set.add(line[4:-5]) except: print("Malformed Data Recieved") self.assertEqual(result_set, {'root/dependency-one/dependency-two'}) def testLongDescription(self): self.createComplexRecipes() self.executeBobJenkinsCmd( "set-options --longdescription myTestJenkinsComplex") self.executeBobJenkinsCmd("push -q myTestJenkinsComplex") send = self.jenkinsMock.getServerData() result_set = set() try: for i in send: if i[0] == '/createItem?name=dependency-two': for items in ElementTree.fromstring( i[1]).iter('description'): for line in [x for x in items.itertext() ][0].splitlines(): if line.startswith('<li>') and line.endswith( '</li>'): result_set.add(line[4:-5]) except: print("Malformed Data Recieved") self.assertEqual( result_set, {'root/dependency-two', 'root/dependency-one/dependency-two'})