Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 0 additions & 49 deletions google-bazel-bot/bazel-bot/bazelbot_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
parser.add_argument(
"--llvm_git_repo", type=str, help="Absolute path to LLVM repo", required=True
)
parser.add_argument(
"--bot_state_file", type=str, help="Bot state file", default="bot_state.log"
)
parser.add_argument("--poll_interval", type=int, help="Polling interval", default=120)
parser.add_argument("--create_prs", action="store_true", help="Whether to create PRs.")
parser.add_argument(
Expand Down Expand Up @@ -61,7 +58,6 @@ def __init__(
git_repo: utils.LocalGitRepo,
creds: utils.CredentialManager,
build_processor: utils.BuildProcessor,
state_file,
poll_interval,
):
# Injectables
Expand All @@ -74,45 +70,8 @@ def __init__(
self.last_processed_build = 0
self.last_processed_state: utils.BuildState = utils.BuildState.UNKNOWN
self.last_processed_sha: str = ""
self.state_file = state_file
self.poll_interval = poll_interval

def load_state(self):
"""Loads the last commit sha from file and find the status of that build."""
if not os.path.exists(self.state_file):
logger.info("No state file found. Will initialize state on first run.")
return

try:
with open(self.state_file, "r") as f:
self.last_processed_sha = f.read().strip()

# Local build to find the last processed build state
logging.info(
f"Finding build state for {self.last_processed_sha} by running build locally..."
)
self.git_repo.checkout_commit(self.last_processed_sha)
build_result = self.command_processor.run_bazel_build()
self.last_processed_state = (
utils.BuildState.PASSED
if build_result.success
else utils.BuildState.FAILED
)
logger.info(
f"Loaded state: last processed sha {self.last_processed_sha} with state {self.last_processed_state}."
)
except Exception as e:
logger.error(f"Failed to load state file: {e}.")
self.last_processed_sha = ""

def save_state(self):
"""Saves current commit sha into a file."""
try:
with open(self.state_file, "w") as f:
f.write(self.last_processed_sha)
except Exception as e:
logger.error(f"Failed to save state: {e}")

def wait(self, seconds):
"""Sleeps for a given number of seconds"""
time.sleep(seconds)
Expand Down Expand Up @@ -151,11 +110,6 @@ def repair_build(self, build: utils.BuildInfo) -> bool:
else:
record.fixed_by = FixTool.NOT_FIXED

with open("summary." + self.state_file, "a") as summary_file:
summary_file.write(
f"{record.timestamp},{record.commit},{record.fixed_by}\n"
)

return record.fixed_by != FixTool.NOT_FIXED

def run_buildifier_on_changed_files(self) -> bool:
Expand Down Expand Up @@ -267,7 +221,6 @@ def set_state_from_latest_build(self) -> bool:
if latest_build:
self.last_processed_sha = latest_build.commit
self.last_processed_state = latest_build.state
self.save_state()
return True

logger.error("Could not init state from latest build.")
Expand Down Expand Up @@ -386,15 +339,13 @@ def test_commits(bot, test_commits_file):
git_repo,
creds_manager,
build_processor,
args.bot_state_file,
args.poll_interval,
)
if args.test_commits:
test_commits(bot, args.test_commits)
exit(0)

logger.info("Bazel Bot entering main loop...")
bot.load_state()
bot.run()
print("Exiting Bazel Bot Server...")
exit(1)
66 changes: 14 additions & 52 deletions google-bazel-bot/bazel-bot/bazelbot_server_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,24 +104,6 @@ def test_local_build_processor(self):
self.assertEqual(builds[0].commit, "sha_old")
self.assertEqual(builds[1].commit, "sha_new")

@mock.patch("builtins.open", new_callable=mock.mock_open, read_data="last_sha")
@mock.patch("os.path.exists")
def test_bazel_repair_bot_load_state(self, mock_exists, mock_file):
mock_exists.return_value = True
cmd_processor = mock.MagicMock()
git_repo = mock.MagicMock()
creds = mock.MagicMock()
build_processor = mock.MagicMock()

cmd_processor.run_bazel_build.return_value = mock.MagicMock(success=True)

bot = bazelbot_server.BazelRepairBot(
cmd_processor, git_repo, creds, build_processor, "state.txt", 10
)
bot.load_state()
self.assertEqual(bot.last_processed_sha, "last_sha")
self.assertEqual(bot.last_processed_state, utils.BuildState.PASSED)

@mock.patch("bazelbot_server.asyncio.run")
def test_process_failure_with_ai(self, mock_asyncio_run):
cmd_processor = mock.MagicMock()
Expand All @@ -131,7 +113,7 @@ def test_process_failure_with_ai(self, mock_asyncio_run):
build_processor = mock.MagicMock()

bot = bazelbot_server.BazelRepairBot(
cmd_processor, git_repo, creds, build_processor, "state.txt", 10
cmd_processor, git_repo, creds, build_processor, 10
)
build_info = utils.BuildInfo("sha1", utils.BuildState.FAILED, [], 1)

Expand Down Expand Up @@ -163,7 +145,7 @@ def test_process_failure_with_ai_past_fixes(
build_processor = mock.MagicMock()

bot = bazelbot_server.BazelRepairBot(
cmd_processor, git_repo, creds, build_processor, "state.txt", 10
cmd_processor, git_repo, creds, build_processor, 10
)
build_info = utils.BuildInfo("sha1", utils.BuildState.FAILED, [], 1)

Expand Down Expand Up @@ -203,7 +185,7 @@ def test_process_failure_with_bant(self):
build_processor = mock.MagicMock()

bot = bazelbot_server.BazelRepairBot(
cmd_processor, git_repo, creds, build_processor, "state.txt", 10
cmd_processor, git_repo, creds, build_processor, 10
)
build_info = utils.BuildInfo(
"sha1", utils.BuildState.FAILED, ["//target:foo"], 1
Expand All @@ -229,11 +211,9 @@ def test_validate_before_publishing(self):
creds = mock.MagicMock()
build_processor = mock.MagicMock()

# Avoid load_state logic
with mock.patch.object(bazelbot_server.BazelRepairBot, "load_state"):
bot = bazelbot_server.BazelRepairBot(
cmd_processor, git_repo, creds, build_processor, "state.txt", 10
)
bot = bazelbot_server.BazelRepairBot(
cmd_processor, git_repo, creds, build_processor, 10
)

# Case 1: Repo not dirty -> False
git_repo.is_repo_dirty.return_value = False
Expand Down Expand Up @@ -263,10 +243,9 @@ def test_repair_build_logic(self):
git_repo = mock.MagicMock()
creds = mock.MagicMock()
build_processor = mock.MagicMock()
with mock.patch.object(bazelbot_server.BazelRepairBot, "load_state"):
bot = bazelbot_server.BazelRepairBot(
cmd_processor, git_repo, creds, build_processor, "state.txt", 10
)
bot = bazelbot_server.BazelRepairBot(
cmd_processor, git_repo, creds, build_processor, 10
)

build_info = utils.BuildInfo("sha1", utils.BuildState.FAILED, [], 1)

Expand All @@ -289,35 +268,18 @@ def test_repair_build_logic(self):
bot.process_failure_with_ai.return_value = False
self.assertFalse(bot.repair_build(build_info))

@mock.patch("builtins.open", new_callable=mock.mock_open)
def test_save_state(self, mock_file):
cmd_processor = mock.MagicMock()
git_repo = mock.MagicMock()
creds = mock.MagicMock()
build_processor = mock.MagicMock()
with mock.patch.object(bazelbot_server.BazelRepairBot, "load_state"):
bot = bazelbot_server.BazelRepairBot(
cmd_processor, git_repo, creds, build_processor, "state.txt", 10
)
bot.last_processed_sha = "saved_sha"
bot.save_state()

mock_file.assert_called_with("state.txt", "w")
mock_file().write.assert_called_with("saved_sha")

def test_run_logic(self):
cmd_processor = mock.MagicMock()
git_repo = mock.MagicMock()
creds = mock.MagicMock()
build_processor = mock.MagicMock()

# Initialize bot with known state
with mock.patch.object(bazelbot_server.BazelRepairBot, "load_state"):
bot = bazelbot_server.BazelRepairBot(
cmd_processor, git_repo, creds, build_processor, "state.txt", 10
)
bot.last_processed_sha = "init_sha"
bot.last_processed_state = utils.BuildState.PASSED
bot = bazelbot_server.BazelRepairBot(
cmd_processor, git_repo, creds, build_processor, 10
)
bot.last_processed_sha = "init_sha"
bot.last_processed_state = utils.BuildState.PASSED

# Define the sequence of builds
builds = [
Expand Down