def test_update_project(self): repository = ProjectRepository() project = self.create_project(name=u"Test Project") elixir.session.flush() elixir.session.commit() update = repository.get(project_id=project.id) self.assertEqual(update.id, project.id) self.assertEqual(update.name, project.name) self.assertEqual(update.build_script, project.build_script) update.name = u"Some Other Project" update.build_script = u"make build" update.scm_repository = u"new_repo" repository.update(update, [], []) elixir.session.flush() elixir.session.commit() updated = repository.get(project_id=project.id) self.assertEqual(updated.id, project.id) self.assertEqual(updated.name, u"Some Other Project") self.assertEqual(updated.build_script, u"make build") self.assertEqual(updated.scm_repository, u"new_repo")
def test_get_all_projects_as_dictionary(self): repository = ProjectRepository() project = self.create_project(name=u"Test Project") project2 = self.create_project(name=u"Test Project2") project3 = self.create_project(name=u"Test Project3") elixir.session.flush() elixir.session.commit() projects = repository.get_all_as_dictionary() self.failUnless(isinstance(projects, dict)) self.assertEqual(len(projects.keys()), 3) self.assertEqual(projects["test project"].id, project.id) self.assertEqual(projects["test project"].name, project.name) self.assertEqual(projects["test project"].build_script, project.build_script) self.assertEqual(projects["test project"].scm_repository, project.scm_repository) self.assertEqual(projects["test project2"].id, project2.id) self.assertEqual(projects["test project2"].name, project2.name) self.assertEqual(projects["test project2"].build_script, project2.build_script) self.assertEqual(projects["test project2"].scm_repository, project2.scm_repository) self.assertEqual(projects["test project3"].id, project3.id) self.assertEqual(projects["test project3"].name, project3.name) self.assertEqual(projects["test project3"].build_script, project3.build_script) self.assertEqual(projects["test project3"].scm_repository, project3.scm_repository)
def test_delete_project(self): repository = ProjectRepository() project = repository.create(name=u"Test Project", build_script=u"make test", scm_repository="git_repo1") repository.delete(project.id) projects = repository.get_all() self.assertEqual(len(projects), 0)
def test_get_project(self): repository = ProjectRepository() project = repository.create(name=u"Test Project", build_script=u"make test", scm_repository="git_repo") retrieved = repository.get(project_id=project.id) self.assertEqual(retrieved.id, project.id) self.assertEqual(retrieved.name, project.name) self.assertEqual(retrieved.build_script, project.build_script) self.assertEqual(retrieved.scm_repository, project.scm_repository)
def test_get_project_by_name(self): repository = ProjectRepository() project = self.create_project(name=u"Test Project") elixir.session.flush() elixir.session.commit() retrieved = repository.get_project_by_name(project_name="Test Project") self.assertEqual(retrieved.id, project.id) self.assertEqual(retrieved.name, project.name) self.assertEqual(retrieved.build_script, project.build_script) self.assertEqual(retrieved.scm_repository, project.scm_repository)
class BuildService(object): Success = "SUCCESS" Failure = "FAILURE" def __init__(self, repository=None, scm=None, executer=None, base_path=join(root_path,'skink','build')): if not repository: self.repository = ProjectRepository() else: self.repository = repository if not scm: self.scm = GitRepository(base_path) else: self.scm = scm if not executer: self.executer = ShellExecuter() else: self.executer = executer self.base_path = base_path def build_project(self, project_id): log = ["Build started at %s" % datetime.now()] status = BuildService.Failure scm_status = ScmResult.Failed project = self.repository.get(project_id) build = Build(datetime.now(), status, scm_status, "", project) scm_creation_result = self.scm.create_or_update(project) build.scm_status = scm_creation_result.status if scm_creation_result.status == ScmResult.Failed: log.append(scm_creation_result.log) status = BuildService.Failure else: log.append("Downloaded code from %s" % project.scm_repository) execute_result = self.executer.execute(project.build_script, scm_creation_result.repository_path) log.append("Executed %s" % project.build_script) log.append("Exit Code: %s" % execute_result.exit_code) log.append("Run Log:") log.append(execute_result.run_log) status = execute_result.exit_code == 0 and BuildService.Success or BuildService.Failure build.status = status build.log = "\n".join(log) self.repository.update(project) return build
def test_create_project(self): repository = ProjectRepository() project = repository.create(name=u"Test Project", build_script=u"make test", scm_repository="git_repo") self.assertNotEqual(project.id, 0) self.assertEqual(project.name, u"Test Project") self.assertEqual(project.build_script, u"make test") self.assertEqual(project.scm_repository, "git_repo") projects = Project.query.all() self.assertEqual(len(projects), 1) self.assertEqual(projects[0].id, project.id) self.assertEqual(projects[0].name, project.name) self.assertEqual(projects[0].build_script, project.build_script) self.assertEqual(projects[0].scm_repository, project.scm_repository)
def test_build_successfully(self): project_repo = ProjectRepository() project = project_repo.create("pyoc", "nosetests", "git://github.com/heynemann/pyoc.git") repo_path = join(root_path, "tests", "functional", "repo") try: shutil.rmtree(repo_path) except: print "The repository folder for the test didn't exist previously. This is not an error!" service = BuildService(base_path=repo_path) build = service.build_project(project.id) self.failUnless(build.scm_status == ScmResult.Created or build.scm_status == ScmResult.Updated)
def test_delete_project(self): repository = ProjectRepository() project = self.create_project(name=u"Test Project") elixir.session.flush() elixir.session.commit() repository.delete(project.id) elixir.session.flush() elixir.session.commit() projects = repository.get_all() self.assertEqual(len(projects), 0)
def create_project(self, name="ProjectA", build_script=u"make test", scm_repository="git_repo", monitor_changes=True, tabs=None): self.project_repository = ProjectRepository() return self.project_repository.create(name=name, build_script=build_script, scm_repository=scm_repository, monitor_changes=monitor_changes, tabs=tabs, file_locators=None)
def test_get_all_projects(self): repository = ProjectRepository() project = repository.create(name=u"Test Project", build_script=u"make test", scm_repository="git_repo1") project2 = repository.create(name=u"Test Project2", build_script=u"make build", scm_repository="git_repo2") project3 = repository.create(name=u"Test Project3", build_script=u"make acceptance", scm_repository="git_repo3") projects = repository.get_all() self.assertEqual(len(projects), 3) self.assertEqual(projects[0].id, project.id) self.assertEqual(projects[0].name, project.name) self.assertEqual(projects[0].build_script, project.build_script) self.assertEqual(projects[0].scm_repository, project.scm_repository) self.assertEqual(projects[1].id, project2.id) self.assertEqual(projects[1].name, project2.name) self.assertEqual(projects[1].build_script, project2.build_script) self.assertEqual(projects[1].scm_repository, project2.scm_repository) self.assertEqual(projects[2].id, project3.id) self.assertEqual(projects[2].name, project3.name) self.assertEqual(projects[2].build_script, project3.build_script) self.assertEqual(projects[2].scm_repository, project3.scm_repository)
def test_get_all_projects(self): repository = ProjectRepository() project = self.create_project(name=u"Test Project") project2 = self.create_project(name=u"Test Project2") project3 = self.create_project(name=u"Test Project3") elixir.session.flush() elixir.session.commit() projects = repository.get_all() self.assertEqual(len(projects), 3) self.assertEqual(projects[0].id, project.id) self.assertEqual(projects[0].name, project.name) self.assertEqual(projects[0].build_script, project.build_script) self.assertEqual(projects[0].scm_repository, project.scm_repository) self.assertEqual(projects[1].id, project2.id) self.assertEqual(projects[1].name, project2.name) self.assertEqual(projects[1].build_script, project2.build_script) self.assertEqual(projects[1].scm_repository, project2.scm_repository) self.assertEqual(projects[2].id, project3.id) self.assertEqual(projects[2].name, project3.name) self.assertEqual(projects[2].build_script, project3.build_script) self.assertEqual(projects[2].scm_repository, project3.scm_repository)
class ProjectController(object): def __init__(self): self.repository = ProjectRepository() @cherrypy.expose @template.output("create_project.html") def new(self): return template.render() @cherrypy.expose def create(self, name, build_script, scm_repository): project = self.repository.create(name=name, build_script=build_script, scm_repository=scm_repository) raise cherrypy.HTTPRedirect("/") @cherrypy.expose @template.output("project_details.html") def default(self, project_id): project = self.repository.get(project_id) return template.render(project=project) @cherrypy.expose def delete(self, project_id): self.repository.delete(project_id) raise cherrypy.HTTPRedirect("/")
def __init__(self, repository=None, scm=None, executer=None, base_path=join(root_path,'skink','build')): if not repository: self.repository = ProjectRepository() else: self.repository = repository if not scm: self.scm = GitRepository(base_path) else: self.scm = scm if not executer: self.executer = ShellExecuter() else: self.executer = executer self.base_path = base_path
def __init__(self, repository=None, pipeline_repository=None, scm=None, executer=None, base_path=join(root_path, SkinkContext.current().build_path)): self.repository = repository if not repository: self.repository = ProjectRepository() self.pipeline_repository = pipeline_repository if not pipeline_repository: self.pipeline_repository = PipelineRepository() self.scm = scm if not scm: self.scm = GitRepository(base_path) self.executer = executer if not executer: self.executer = ShellExecuter() self.base_path = base_path
class BaseFunctionalTest(TestCase): def create_project(self, name="ProjectA", build_script=u"make test", scm_repository="git_repo", monitor_changes=True, tabs=None): self.project_repository = ProjectRepository() return self.project_repository.create(name=name, build_script=build_script, scm_repository=scm_repository, monitor_changes=monitor_changes, tabs=tabs, file_locators=None) def setUp(self): metadata.bind = 'sqlite:///:memory:' metadata.bind.echo = True setup_all(create_tables=True) create_all() def tearDown(self): elixir.session.commit()
def test_update_project(self): repository = ProjectRepository() project = repository.create(name=u"Test Project", build_script=u"make test", scm_repository="git_repo") update = repository.get(project_id=project.id) self.assertEqual(update.id, project.id) self.assertEqual(update.name, project.name) self.assertEqual(update.build_script, project.build_script) update.name = u"Some Other Project" update.build_script = u"make build" update.scm_repository = u"new_repo" repository.update(update) updated = repository.get(project_id=project.id) self.assertEqual(updated.id, project.id) self.assertEqual(updated.name, u"Some Other Project") self.assertEqual(updated.build_script, u"make build") self.assertEqual(updated.scm_repository, u"new_repo")
class BuildService(object): Success = u"SUCCESS" Failure = u"FAILURE" def __init__(self, repository=None, pipeline_repository=None, scm=None, executer=None, base_path=join(root_path, SkinkContext.current().build_path)): self.repository = repository if not repository: self.repository = ProjectRepository() self.pipeline_repository = pipeline_repository if not pipeline_repository: self.pipeline_repository = PipelineRepository() self.scm = scm if not scm: self.scm = GitRepository(base_path) self.executer = executer if not executer: self.executer = ShellExecuter() self.base_path = base_path def build_project(self, project_id): ctx = SkinkContext.current() log = ["Build started at %s" % datetime.now()] status = BuildService.Failure scm_status = ScmResult.Failed project = self.repository.get(project_id) PluginEvents.on_before_build(project) ctx.projects_being_built.append(project_id) last_build_number = project.get_last_build_number() build = Build() build.date = datetime.now() build.status = status build.scm_status = scm_status build.log = "" build.project = project scm_creation_result = self.scm.create_or_update(project) build.scm_status = scm_creation_result.status if scm_creation_result.status == ScmResult.Failed: log.append(scm_creation_result.log) status = BuildService.Failure else: log.append("Downloaded code from %s (%s)" % (project.scm_repository, scm_creation_result.status)) execute_result = self.executer.execute(project.build_script, scm_creation_result.repository_path, timeout=ctx.build_timeout) log.append("Executed %s" % project.build_script) log.append("Exit Code: %s" % execute_result.exit_code) log.append("Run Log:") log.append(execute_result.run_log) status = execute_result.exit_code == 0 and BuildService.Success or BuildService.Failure for command in project.tabs: build_tab = BuildTab(name=command.name, command=command.command, content_type=command.content_type, build=build) result = self.executer.execute(command.command, scm_creation_result.repository_path) build_tab.log = result.run_log for file_locator in project.file_locators: file_locator_path = join(self.base_path, project.name, file_locator.locator) print "Finding files for locator %s" % file_locator_path files = glob.glob(file_locator_path) print "%d files found" % len(files) for f in files: print "Adding file %s" % f filename = split(f)[-1] stream = open(f, 'rb') content = stream.read() stream.close() build_file = BuildFile(name=filename, original_path=f, content=content, build=build) build.number = last_build_number + 1 build.status = status build.log = "\n".join(log) build.commit_number = force_unicode(scm_creation_result.last_commit["commit_number"]) build.commit_author = force_unicode(scm_creation_result.last_commit["author"]) build.commit_committer = force_unicode(scm_creation_result.last_commit["committer"]) build.commit_author_date = scm_creation_result.last_commit["author_date"] build.commit_committer_date = scm_creation_result.last_commit["committer_date"] build.commit_text = force_unicode(scm_creation_result.last_commit["subject"]) self.repository.update(project, project.tabs, [locator.locator for locator in project.file_locators]) ctx.projects_being_built.remove(project_id) if (build.status == BuildService.Success): PluginEvents.on_build_successful(project, build) self.process_pipelines_for(project) else: PluginEvents.on_build_failed(project, build) return build def delete_scm_repository(self, project): self.scm.remove_repository(project) def process_pipelines_for(self, project): pipelines = self.pipeline_repository.get_all_pipelines_for(project) for pipeline in pipelines: for i in range(len(pipeline.items)): if i < len(pipeline.items) - 1: if pipeline.items[i].project.id == project.id: print "Adding project %d to the queue because it's in the same pipeline as project %s" % (pipeline.items[i+1].project.id, pipeline.items[i].project.name) SkinkContext.current().build_queue.append(pipeline.items[i+1].project.id)
def is_db_created(cls): rep = ProjectRepository() try: projects = rep.get_all() except Exception, err: return False
def dashboard(self): repository = ProjectRepository() projects = repository.get_all() return template.render(authenticated=self.authenticated(), projects=projects)
class ProjectController(BaseController): def __init__(self): self.repository = ProjectRepository() self.build_service = BuildService() @authenticated() @template.output("create_project.html") def new(self): return template.render(authenticated=self.authenticated(), project=None) @authenticated() @template.output("create_project.html") def edit(self, project_id): project = self.repository.get(project_id) return template.render(authenticated=self.authenticated(), project=project) def __process_tabs_for(self, data): tabs = None if data.has_key("additional_tab_name"): tab_names = [name for name in data["additional_tab_name"] if name != u""] tab_commands = [command for command in data["additional_tab_command"] if command != u""] tab_content_types = [ content_type for content_type in data["additional_tab_content_type"] if content_type != u"" ][1:] if len(tab_names) > len(tab_commands) or len(tab_names) > len(tab_content_types): raise ValueError("The number of tabs, commands and content types MUST be the same.") tabs = [] for tab_index in range(len(tab_names)): tab = ProjectTab( name=tab_names[tab_index], command=tab_commands[tab_index], content_type=tab_content_types[tab_index], ) tabs.append(tab) return tabs def __process_file_locators_for(self, data): locators = None if data.has_key("additional_file_locator"): locators = [locator for locator in data["additional_file_locator"] if locator != u""] return locators @authenticated() def create(self, name, build_script, scm_repository, monitor_changes=None, **data): project = self.repository.create( name=name, build_script=build_script, scm_repository=scm_repository, monitor_changes=not monitor_changes is None, tabs=self.__process_tabs_for(data), file_locators=self.__process_file_locators_for(data), ) PluginEvents.on_project_created(project) raise cherrypy.HTTPRedirect("/") @authenticated() def update(self, project_id, name, build_script, scm_repository, monitor_changes=None, **data): project = self.repository.get(project_id) project.name = name project.build_script = build_script project.scm_repository = scm_repository project.monitor_changes = not monitor_changes is None self.repository.update( project, self.__process_tabs_for(data), file_locators=self.__process_file_locators_for(data) ) PluginEvents.on_project_updated(project) raise cherrypy.HTTPRedirect("/") @authenticated() def delete(self, project_id): project = self.repository.get(project_id) self.repository.delete(project_id) self.build_service.delete_scm_repository(project) PluginEvents.on_project_deleted(project) raise cherrypy.HTTPRedirect("/") @authenticated() def build(self, project_id): print "Adding project %s to the queue" % project_id SkinkContext.current().build_queue.append(project_id) raise cherrypy.HTTPRedirect("/project/%s" % project_id) @template.output("current_build.html") def current_build_report(self, **data): return template.render(authenticated=self.authenticated()) def current_status(self, **data): ctx = SkinkContext.current() result = {} result["project"] = ctx.current_project and ctx.current_project.name or "" result["project_id"] = ctx.current_project and ctx.current_project.id or "" result["command"] = ctx.current_command result["log"] = ctx.current_log and u"<br />".join(unicode(ctx.current_log).splitlines()[-30:]) or "" return demjson.encode(result) def build_status(self, **data): ctx = SkinkContext.current() projects = self.repository.get_all() projects_being_built = [int(project_id) for project_id in ctx.projects_being_built] result = {} for project in projects: if project.id in projects_being_built: result[project.id] = (project.name, "BUILDING") else: result[project.id] = ( project.name, (project.last_builds is not None and len(project.last_builds) > 0) and "BUILT" or "UNKNOWN", ) return "\n".join(["%s=%s@@%s" % (k, v[0], v[1]) for k, v in result.items()]) @template.output("project_details.html") def details(self, project_id): return self.render_details(project_id) @template.output("project_details.html") def build_details(self, project_id, build_id): return self.render_details(project_id, build_id) def build_tab_details(self, build_tab_id): return self.repository.get_build_tab_by_id(build_tab_id=build_tab_id).log def build_file_details(self, build_file_id): build_file = self.repository.get_build_file_by_id(build_file_id=build_file_id) response.headers["Content-Type"] = "application/x-download" response.headers["Content-Disposition"] = 'attachment; filename="%s"' % build_file.name response.headers["Accept-Ranges"] = "bytes" response.headers["Content-Length"] = len(build_file.content) response.body = build_file.content return response.body def get_all_status(self, **data): projects = self.repository.get_all() serialized_projects = [] for project in projects: serialized_projects.append(project.to_dict()) values = {} values["projects"] = serialized_projects cherrypy.response.headers["Content-Type"] = "application/json" return demjson.encode(values) def render_details(self, project_id, build_id=None): project = self.repository.get(project_id) if not build_id: build = project.last_builds and project.last_builds[0] or None else: build = project.get_build_by_id(int(build_id)) build_log = "" if build and build.log: build_log = highlight(build.log, BashLexer(), HtmlFormatter()) return template.render( authenticated=self.authenticated(), project=project, current_build=build, build_log=build_log )
def __init__(self): self.repository = ProjectRepository() self.build_service = BuildService()
def __init__(self): self.repository = ProjectRepository()
def index(self): repository = ProjectRepository() projects = repository.get_all() return template.render(projects=projects)