blob: b03520c7d62b3e6cf380e74d83c1cc1e8882d4a2 [file] [log] [blame]
# Copyright (C) 2019 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import abc
import os
import random
import string
import git
from . import abstract
class AbstractPushAction(abstract.AbstractAction):
def __init__(self, refspec, project_name, probability=0.2):
super().__init__(url=None, user=None, pwd=None, probability=probability)
self.project_name = project_name
self.change_types = [self._add_file, self._modify_file, self._delete_file]
self.local_repo_path = os.path.join("/tmp", self.project_name)
self.repo = git.Repo(self.local_repo_path)
self.refspec = refspec
@abc.abstractmethod
def _prepare(self):
pass
def _execute_action(self):
self.repo.git.checkout("origin/master")
self._prepare()
if os.path.exists(self.local_repo_path):
num_commits = random.randint(1, 5)
for _ in range(num_commits):
self._create_commit()
self.repo.remotes.origin.push(refspec=self.refspec)
self.was_executed = True
self._log_result(
"Pushed %d commits to project %s using refspec %s"
% (num_commits, self.project_name, self.refspec)
)
def _create_commit(self):
change_type_choice = random.choice(self.change_types)
change_type_choice()
self.repo.index.commit("%s\n\n" % self._create_random_string(16))
def _add_file(self):
while True:
file_name = self._create_random_string(8)
file_path = os.path.join("/tmp", self.project_name, file_name)
if os.path.exists(file_path):
continue
with open(file_path, "w+") as f:
self.log.info("Adding file %s to commit", file_name)
f.write(self._create_random_string(random.randint(1, 2000)))
self.repo.index.add([file_name])
break
def _modify_file(self):
files = self._get_files_in_repo_workdir()
if not files:
self.log.info(
"Repository does not contain any files yet. Adding instead of modifying"
)
self._add_file()
return
file_name = random.choice(files)
file_path = os.path.join("/tmp", self.project_name, file_name)
with open(file_path, "a+") as f:
self.log.info("Modifying file %s for commit", file_name)
f.write(self._create_random_string(random.randint(1, 2000)))
self.repo.index.add([file_name])
def _delete_file(self):
files = self._get_files_in_repo_workdir()
if not files:
self.log.info(
"Repository does not contain any files yet. Adding instead of deleting"
)
self._add_file()
return
file_name = random.choice(files)
self.log.info("Deleting file %s to commit", file_name)
os.remove(os.path.join("/tmp", self.project_name, file_name))
self.repo.index.remove([file_name])
def _get_files_in_repo_workdir(self):
files = list()
for (dirpath, _, filenames) in os.walk(os.path.join("/tmp", self.project_name)):
if ".git" not in dirpath:
files += [os.path.join(dirpath, file) for file in filenames]
return files
@staticmethod
def _create_random_string(length):
allowed_symbols = string.ascii_letters + string.digits
return "".join([random.choice(allowed_symbols) for n in range(length)])