Skip to content

Commit

Permalink
Merge pull request #81 from nuclearcat/fix-bisect
Browse files Browse the repository at this point in the history
fix(bisect.py): Fix initial tree creation and params rename
  • Loading branch information
aliceinwire authored Jan 17, 2025
2 parents 70d059c + c5b6427 commit 4d94070
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 63 deletions.
20 changes: 10 additions & 10 deletions docs/checkout.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ This might be useful in several cases:
- You want to create snapshot of the test results on specific tags (releases, etc).
- Use this command for regression bisection

This command can execute all tests configured for particular tree/branch, or you can provide jobfilter to execute specific tests and builds.
This command can execute all tests configured for particular tree/branch, or you can provide job-filter to execute specific tests and builds.

Example:
```sh
kci-dev checkout --giturl https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git --branch master --commit f06021a18fcf8d8a1e79c5e0a8ec4eb2b038e153 --jobfilter "kbuild-gcc-12-x86"
kci-dev checkout --giturl https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git --branch master --commit f06021a18fcf8d8a1e79c5e0a8ec4eb2b038e153 --job-filter "kbuild-gcc-12-x86"
```

Where:
- `giturl` is the URL of the git repository to test.
- `branch` is the branch of the git repository to test.
- `commit` is the commit hash to test.
- `jobfilter` is the job filter to use for the test (optional parameter)
- `platformfilter` is the platform filter (usually it is name of hardware platform for group of devices) to use for the test (optional parameter)
- `job-filter` is the job filter to use for the test (optional parameter)
- `platform-filter` is the platform filter (usually it is name of hardware platform for group of devices) to use for the test (optional parameter)

To figure out correct jobfilter and platformfilter, you need to check test json node. For example:
To figure out correct job-filter and platform-filter, you need to check test json node. For example:
```json
{
"id": "670f0c27493b6b8188c7667c",
Expand Down Expand Up @@ -81,7 +81,7 @@ To figure out correct jobfilter and platformfilter, you need to check test json
"kernel_type": "image"
},
"debug": null,
"jobfilter": null,
"job-filter": null,
"platform_filter": null,
"created": "2024-10-16T00:43:19.079000",
"updated": "2024-10-16T02:22:58.113000",
Expand All @@ -94,9 +94,9 @@ To figure out correct jobfilter and platformfilter, you need to check test json
}
```

In this example, the jobfilter is `tast-mm-misc-arm64-qualcomm` for test, if you look into path, you can figure out also build job named and the platformfilter is `kbuild-gcc-12-arm64-chromeos-qualcomm` and in data/platform: `sc7180-trogdor-lazor-limozeen`. So complete command to test this job would be:
In this example, the job-filter is `tast-mm-misc-arm64-qualcomm` for test, if you look into path, you can figure out also build job named and the platform-filter is `kbuild-gcc-12-arm64-chromeos-qualcomm` and in data/platform: `sc7180-trogdor-lazor-limozeen`. So complete command to test this job would be:
```sh
kci-dev checkout --giturl https://github.com/kernelci/linux.git --branch staging-mainline --commit c862449c840a37bbe797a0b719881449beac75ca --jobfilter tast-mm-misc-arm64-qualcomm --jobfilter kbuild-gcc-12-arm64-chromeos-qualcomm --platformfilter sc7180-trogdor-lazor-limozeen
kci-dev checkout --giturl https://github.com/kernelci/linux.git --branch staging-mainline --commit c862449c840a37bbe797a0b719881449beac75ca --job-filter tast-mm-misc-arm64-qualcomm --job-filter kbuild-gcc-12-arm64-chromeos-qualcomm --platform-filter sc7180-trogdor-lazor-limozeen
```

Other options:
Expand All @@ -111,7 +111,7 @@ Additionally, you can use --watch option to watch the progress of the test.

After executing the command, you will see the output similar to the following:
```sh
./kci-dev.py checkout --giturl https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git --branch master --tipoftree --jobfilter baseline-nfs-arm64-qualcomm --jobfilter kbuild-gcc-12-arm64-chromeos-qualcomm --watch
./kci-dev.py checkout --giturl https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git --branch master --tipoftree --job-filter baseline-nfs-arm64-qualcomm --job-filter kbuild-gcc-12-arm64-chromeos-qualcomm --watch
api connect: https://staging.kernelci.org:9100/
Retrieving latest commit on tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git branch: master
Commit to checkout: d3d1556696c1a993eec54ac585fe5bf677e07474
Expand Down Expand Up @@ -170,7 +170,7 @@ Together with --watch option, you can use --test option to wait for particular t

For example:
```sh
kci-dev.py checkout --giturl https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git --branch master --tipoftree --jobfilter baseline-nfs-arm64-qualcomm --jobfilter kbuild-gcc-12-arm64-chromeos-qualcomm --platformfilter sc7180-trogdor-kingoftown --watch --test crit
kci-dev.py checkout --giturl https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git --branch master --tipoftree --job-filter baseline-nfs-arm64-qualcomm --job-filter kbuild-gcc-12-arm64-chromeos-qualcomm --platform-filter sc7180-trogdor-kingoftown --watch --test crit
```

This command will wait for the test results of the test with the name `crit`.
Expand Down
69 changes: 38 additions & 31 deletions kcidev/subcommands/bisect.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
"good": "",
"bad": "",
"history": [],
"jobfilter": [],
"platformfilter": [],
"job_filter": [],
"platform_filter": [],
"test": "",
"workdir": "",
"bisect_init": False,
Expand Down Expand Up @@ -59,8 +59,8 @@ def print_state(state):
click.secho("bad: " + state["bad"], fg="green")
click.secho("retryfail: " + str(state["retryfail"]), fg="green")
click.secho("history: " + str(state["history"]), fg="green")
click.secho("jobfilter: " + str(state["jobfilter"]), fg="green")
click.secho("platformfilter: " + str(state["platformfilter"]), fg="green")
click.secho("job_filter: " + str(state["job_filter"]), fg="green")
click.secho("platform_filter: " + str(state["platform_filter"]), fg="green")
click.secho("test: " + state["test"], fg="green")
click.secho("workdir: " + state["workdir"], fg="green")
click.secho("bisect_init: " + str(state["bisect_init"]), fg="green")
Expand All @@ -76,7 +76,9 @@ def git_exec_getcommit(cmd):
click.secho("Executing git command: " + " ".join(cmd), fg="green")
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode != 0:
click.secho("git command return failed", fg="red")
click.secho("git command return failed. Error:", fg="red")
click.secho(result.stderr, fg="red")
click.secho(result.stdout, fg="red")
sys.exit(1)
lines = result.stdout.split(b"\n")
if len(lines) < 2:
Expand Down Expand Up @@ -133,6 +135,20 @@ def init_bisect(state):
return commitid


def update_tree(workdir, branch, giturl):
if not os.path.exists(workdir):
click.secho(
"Cloning repository (this might take significant time!)", fg="green"
)
repo = Repo.clone_from(giturl, workdir)
repo.git.checkout(branch)
else:
click.secho("Pulling repository", fg="green")
repo = Repo(workdir)
repo.git.checkout(branch)
repo.git.pull()


def bisection_loop(state):
olddir = os.getcwd()
os.chdir(state["workdir"])
Expand All @@ -154,12 +170,12 @@ def bisection_loop(state):
commit,
"--watch",
]
# jobfilter is array, so we need to add each element as a separate argument
for job in state["jobfilter"]:
cmd.append("--jobfilter")
# job_filter is array, so we need to add each element as a separate argument
for job in state["job_filter"]:
cmd.append("--job_filter")
cmd.append(job)
for platform in state["platformfilter"]:
cmd.append("--platformfilter")
for platform in state["platform_filter"]:
cmd.append("--platform_filter")
cmd.append(platform)
result = kcidev_exec(cmd)
try:
Expand Down Expand Up @@ -199,8 +215,8 @@ def bisection_loop(state):
@click.option("--workdir", help="define the repository origin", default="kcidev-src")
@click.option("--ignorestate", help="ignore save state", is_flag=True)
@click.option("--statefile", help="state file", default="state.json")
@click.option("--jobfilter", help="filter the job", multiple=True)
@click.option("--platformfilter", help="filter the platform", multiple=True)
@click.option("--job-filter", help="filter the job", multiple=True)
@click.option("--platform-filter", help="filter the platform", multiple=True)
@click.option("--test", help="Test expected to fail")

# test
Expand All @@ -215,8 +231,8 @@ def bisect(
workdir,
ignorestate,
statefile,
jobfilter,
platformfilter,
job_filter,
platform_filter,
test,
):
config = ctx.obj.get("CFG")
Expand All @@ -239,11 +255,11 @@ def bisect(
if not bad:
click.secho("--bad is required", fg="red")
return
if not jobfilter:
click.secho("--jobfilter is required", fg="red")
if not job_filter:
click.secho("--job_filter is required", fg="red")
return
if not platformfilter:
click.secho("--platformfilter is required", fg="red")
if not platform_filter:
click.secho("--platform_filter is required", fg="red")
return
if not test:
click.secho("--test is required", fg="red")
Expand All @@ -254,24 +270,15 @@ def bisect(
state["good"] = good
state["bad"] = bad
state["retryfail"] = retryfail
state["jobfilter"] = jobfilter
state["platformfilter"] = platformfilter
state["job_filter"] = job_filter
state["platform_filter"] = platform_filter
state["test"] = test
state["workdir"] = workdir
update_tree(workdir, branch, giturl)
save_state(state, state_file)
else:
print_state(state)

# if workdir doesnt exist, clone the repository
if not os.path.exists(workdir):
click.secho("Cloning repository", fg="green")
repo = Repo.clone_from(giturl, workdir)
repo.git.checkout(branch)
else:
click.secho("Pulling repository", fg="green")
repo = Repo(workdir)
repo.git.checkout(branch)
repo.git.pull()
update_tree(workdir, branch, giturl)

if not state["bisect_init"]:
state["next_commit"] = init_bisect(state)
Expand Down
44 changes: 22 additions & 22 deletions kcidev/subcommands/checkout.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ def send_checkout_full(baseurl, token, **kwargs):
"url": kwargs["giturl"],
"branch": kwargs["branch"],
"commit": kwargs["commit"],
"jobfilter": kwargs["jobfilter"],
"jobfilter": kwargs["job_filter"],
}
if "platformfilter" in kwargs:
data["platformfilter"] = kwargs["platformfilter"]
if "platform_filter" in kwargs:
data["platformfilter"] = kwargs["platform_filter"]
jdata = json.dumps(data)
print(jdata)
try:
Expand Down Expand Up @@ -107,13 +107,13 @@ def check_node(node):
return "FAIL"


def watch_jobs(baseurl, token, treeid, jobfilter, test):
# we need to add to jobfilter "checkout" node
jobfilter = list(jobfilter)
jobfilter.append("checkout")
def watch_jobs(baseurl, token, treeid, job_filter, test):
# we need to add to job_filter "checkout" node
job_filter = list(job_filter)
job_filter.append("checkout")
while True:
inprogress = 0
joblist = jobfilter.copy()
joblist = job_filter.copy()
nodes = retrieve_treeid_nodes(baseurl, token, treeid)
if not nodes:
click.secho("No nodes found. Retrying...", fg="yellow")
Expand All @@ -122,17 +122,17 @@ def watch_jobs(baseurl, token, treeid, jobfilter, test):
time_local = time.localtime()
click.echo(f"Current time: {time.strftime('%Y-%m-%d %H:%M:%S', time_local)}")
click.secho(
f"Total tree nodes {len(nodes)} found. Jobfilter: {jobfilter}", fg="green"
f"Total tree nodes {len(nodes)} found. job_filter: {job_filter}", fg="green"
)

# Tricky part in watch is that we might have one item in jobfilter (job, test),
# Tricky part in watch is that we might have one item in job_filter (job, test),
# but it might spawn multiple nodes with same name
test_result = None
jobs_done_ts = None
for node in nodes:
if node["name"] == test:
test_result = node["result"]
if node["name"] in jobfilter:
if node["name"] in job_filter:
result = check_node(node)
if result == "DONE":
if isinstance(joblist, list) and node["name"] in joblist:
Expand Down Expand Up @@ -219,17 +219,17 @@ def retrieve_tot_commit(repourl, branch):
)
@click.option(
"--watch",
help="Interactively watch for a tasks in jobfilter",
help="Interactively watch for a tasks in job-filter",
is_flag=True,
)
# jobfilter is a list, might be one or more jobs
# job_filter is a list, might be one or more jobs
@click.option(
"--jobfilter",
"--job-filter",
help="Job filter to trigger",
multiple=True,
)
@click.option(
"--platformfilter",
"--platform-filter",
help="Platform filter to trigger",
multiple=True,
)
Expand All @@ -239,17 +239,17 @@ def retrieve_tot_commit(repourl, branch):
)
@click.pass_context
def checkout(
ctx, giturl, branch, commit, jobfilter, platformfilter, tipoftree, watch, test
ctx, giturl, branch, commit, job_filter, platform_filter, tipoftree, watch, test
):
cfg = ctx.obj.get("CFG")
instance = ctx.obj.get("INSTANCE")
url = api_connection(cfg[instance]["pipeline"])
apiurl = cfg[instance]["api"]
token = cfg[instance]["token"]
if not jobfilter:
jobfilter = None
if not job_filter:
job_filter = None
click.secho("No job filter defined. All jobs will be triggered!", fg="yellow")
if watch and not jobfilter:
if watch and not job_filter:
click.secho("No job filter defined. Can't watch for a job(s)!", fg="red")
return
if test and not watch:
Expand All @@ -275,8 +275,8 @@ def checkout(
giturl=giturl,
branch=branch,
commit=commit,
jobfilter=jobfilter,
platformfilter=platformfilter,
job_filter=job_filter,
platform_filter=platform_filter,
watch=watch,
)
if resp and "message" in resp:
Expand All @@ -292,7 +292,7 @@ def checkout(
if test:
click.secho(f"Watching for test result: {test}", fg="green")
# watch for jobs
watch_jobs(apiurl, token, treeid, jobfilter, test)
watch_jobs(apiurl, token, treeid, job_filter, test)


if __name__ == "__main__":
Expand Down

0 comments on commit 4d94070

Please sign in to comment.