Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[forge] rust bindings for indexer/testnet deployer #14547

Merged
merged 17 commits into from
Oct 1, 2024
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
8 changes: 5 additions & 3 deletions .github/workflows/adhoc-forge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@ on:
required: false
type: string
description: The Forge k8s cluster to be used for test
FORGE_ENABLE_HAPROXY:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove this option?

Copy link
Contributor Author

@rustielin rustielin Sep 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to make space for an indexer option. workflow_dispatch has a maximum of 10 inputs unfortunately. We can continue to test HAProxy in continuous forge if necessary, but we can probably remove it from adhoc

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦🏽 I see.

FORGE_ENABLE_INDEXER:
required: false
default: false
type: boolean
description: enable haproxy for the forge test
description: Whether to use indexer
FORGE_NUM_VALIDATORS:
required: false
type: string
Expand Down Expand Up @@ -68,6 +67,7 @@ jobs:
echo "FORGE_TEST_SUITE: ${{ inputs.FORGE_TEST_SUITE }}"
echo "FORGE_CLUSTER_NAME: ${{ inputs.FORGE_CLUSTER_NAME }}"
echo "FORGE_ENABLE_HAPROXY: ${{ inputs.FORGE_ENABLE_HAPROXY }}"
echo "FORGE_ENABLE_INDEXER: ${{ inputs.FORGE_ENABLE_INDEXER }}"
echo "FORGE_NUM_VALIDATORS: ${{ inputs.FORGE_NUM_VALIDATORS }}"
echo "FORGE_NUM_VALIDATOR_FULLNODES: ${{ inputs.FORGE_NUM_VALIDATOR_FULLNODES }}"
echo "FORGE_RETAIN_DEBUG_LOGS: ${{ inputs.FORGE_RETAIN_DEBUG_LOGS }}"
Expand All @@ -79,6 +79,7 @@ jobs:
forgeTestSuite: ${{ inputs.FORGE_TEST_SUITE }}
forgeClusterName: ${{ inputs.FORGE_CLUSTER_NAME }}
forgeEnableHaproxy: ${{ inputs.FORGE_ENABLE_HAPROXY }}
forgeEnableIndexer: ${{ inputs.FORGE_ENABLE_INDEXER }}
forgeNumValidators: ${{ inputs.FORGE_NUM_VALIDATORS }}
forgeNumValidatorFullnodes: ${{ inputs.FORGE_NUM_VALIDATOR_FULLNODES }}

Expand All @@ -94,6 +95,7 @@ jobs:
FORGE_RUNNER_DURATION_SECS: ${{ fromJSON(needs.determine-forge-run-metadata.outputs.forgeRunnerDurationSecs) }} # fromJSON converts to integer
FORGE_CLUSTER_NAME: ${{ needs.determine-forge-run-metadata.outputs.forgeClusterName }}
FORGE_ENABLE_HAPROXY: ${{ needs.determine-forge-run-metadata.outputs.forgeEnableHaproxy }}
FORGE_ENABLE_INDEXER: ${{ needs.determine-forge-run-metadata.outputs.forgeEnableIndexer }}
FORGE_NUM_VALIDATORS: ${{ needs.determine-forge-run-metadata.outputs.forgeNumValidators }}
FORGE_NUM_VALIDATOR_FULLNODES: ${{ needs.determine-forge-run-metadata.outputs.forgeNumValidatorFullnodes }}
FORGE_RETAIN_DEBUG_LOGS: ${{ inputs.FORGE_RETAIN_DEBUG_LOGS }}
15 changes: 7 additions & 8 deletions .github/workflows/workflow-run-forge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ on:
type: boolean
default: false
description: Whether to post the test results comment to Slack
COMMENT_ON_PR:
required: false
type: boolean
default: true
description: Whether to post the test results comment to the PR
TIMEOUT_MINUTES:
required: false
type: number
Expand All @@ -57,6 +52,10 @@ on:
required: false
type: string
description: Whether to use HAPRoxy
FORGE_ENABLE_INDEXER:
required: false
type: boolean
description: Whether to use indexer
FORGE_ENABLE_PERFORMANCE:
required: false
type: string
Expand Down Expand Up @@ -104,14 +103,14 @@ env:
FORGE_RUNNER_DURATION_SECS: ${{ inputs.FORGE_RUNNER_DURATION_SECS }}
FORGE_NAMESPACE: ${{ inputs.FORGE_NAMESPACE }}
FORGE_ENABLE_HAPROXY: ${{ inputs.FORGE_ENABLE_HAPROXY }}
FORGE_ENABLE_INDEXER: ${{ inputs.FORGE_ENABLE_INDEXER }}
FORGE_TEST_SUITE: ${{ inputs.FORGE_TEST_SUITE }}
POST_TO_SLACK: ${{ inputs.POST_TO_SLACK }}
FORGE_ENABLE_FAILPOINTS: ${{ inputs.FORGE_ENABLE_FAILPOINTS }}
FORGE_ENABLE_PERFORMANCE: ${{ inputs.FORGE_ENABLE_PERFORMANCE }}
FORGE_RETAIN_DEBUG_LOGS: ${{ inputs.FORGE_RETAIN_DEBUG_LOGS }}
COMMENT_HEADER: ${{ inputs.COMMENT_HEADER }}
VERBOSE: true
COMMENT_ON_PR: ${{ inputs.COMMENT_ON_PR }}
FORGE_NUM_VALIDATORS: ${{ inputs.FORGE_NUM_VALIDATORS }}
FORGE_NUM_VALIDATOR_FULLNODES: ${{ inputs.FORGE_NUM_VALIDATOR_FULLNODES }}

Expand Down Expand Up @@ -191,7 +190,7 @@ jobs:
run: testsuite/run_forge.sh

- name: Post pre-Forge comment
if: ${{ !inputs.SKIP_JOB && env.COMMENT_ON_PR == 'true' && github.event.number != null }}
if: ${{ !inputs.SKIP_JOB && github.event.number != null }}
uses: marocchino/sticky-pull-request-comment@39c5b5dc7717447d0cba270cd115037d32d28443 # pin@39c5b5dc7717447d0cba270cd115037d32d2844
with:
header: ${{ env.COMMENT_HEADER }}
Expand All @@ -206,7 +205,7 @@ jobs:

- name: Post forge result comment
# Post a Github comment if the run has not been cancelled and if we're running on a PR
if: ${{ !inputs.SKIP_JOB && env.COMMENT_ON_PR == 'true' && github.event.number != null && !cancelled() }}
if: ${{ !inputs.SKIP_JOB && github.event.number != null && !cancelled() }}
uses: marocchino/sticky-pull-request-comment@39c5b5dc7717447d0cba270cd115037d32d28443 # pin@39c5b5dc7717447d0cba270cd115037d32d2844
with:
header: ${{ env.COMMENT_HEADER }}
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ target-out-docker
docker/compose/indexer-grpc/data-service-grpc-server.crt
docker/compose/indexer-grpc/data-service-grpc-server.key


# Doc generation output
*.md.old

Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions testsuite/forge-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ once_cell = { workspace = true }
rand = { workspace = true }
random_word = { workspace = true }
reqwest = { workspace = true }
serde_json = { workspace = true }
serde_yaml = { workspace = true }
tokio = { workspace = true }
url = { workspace = true }
Expand Down
77 changes: 62 additions & 15 deletions testsuite/forge-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ use clap::{Parser, Subcommand};
use futures::stream::{FuturesUnordered, StreamExt};
use once_cell::sync::Lazy;
use rand::{rngs::ThreadRng, seq::SliceRandom, Rng};
use serde_json::{json, Value};
use std::{
env,
num::NonZeroUsize,
Expand Down Expand Up @@ -140,8 +141,8 @@ enum OperatorCommand {
SetNodeImageTag(SetNodeImageTag),
/// Clean up an existing cluster
CleanUp(CleanUp),
/// Resize an existing cluster
Resize(Resize),
/// Create a new cluster for testing purposes
Create(Create),
}

#[derive(Parser, Debug)]
Expand Down Expand Up @@ -193,6 +194,11 @@ struct K8sSwarm {
help = "Retain debug logs and above for all nodes instead of just the first 5 nodes"
)]
retain_debug_logs: bool,
#[clap(
long,
help = "If set, spins up an indexer stack alongside the testnet. Same as --enable-indexer"
)]
enable_indexer: bool,
}

#[derive(Parser, Debug)]
Expand All @@ -217,8 +223,8 @@ struct CleanUp {
}

#[derive(Parser, Debug)]
struct Resize {
#[clap(long, help = "The kubernetes namespace to resize")]
struct Create {
#[clap(long, help = "The kubernetes namespace to create in")]
namespace: String,
#[clap(long, default_value_t = 30)]
num_validators: usize,
Expand All @@ -227,13 +233,13 @@ struct Resize {
#[clap(
long,
help = "Override the image tag used for validators",
default_value = "devnet"
default_value = "main"
)]
validator_image_tag: String,
#[clap(
long,
help = "Override the image tag used for testnet-specific components",
default_value = "devnet"
default_value = "main"
)]
testnet_image_tag: String,
#[clap(
Expand All @@ -248,6 +254,14 @@ struct Resize {
connect_directly: bool,
#[clap(long, help = "If set, enables HAProxy for each of the validators")]
enable_haproxy: bool,
#[clap(long, help = "If set, spins up an indexer stack alongside the testnet")]
enable_indexer: bool,
#[clap(
long,
help = "Override the image tag used for indexer",
requires = "enable_indexer"
)]
indexer_image_tag: Option<String>,
}

// common metrics thresholds:
Expand Down Expand Up @@ -393,6 +407,7 @@ fn main() -> Result<()> {
k8s.reuse,
k8s.keep,
k8s.enable_haproxy,
k8s.enable_indexer,
)
.unwrap(),
&args.options,
Expand Down Expand Up @@ -421,19 +436,51 @@ fn main() -> Result<()> {
}
Ok(())
},
OperatorCommand::Resize(resize) => {
OperatorCommand::Create(create) => {
let kube_client = runtime.block_on(create_k8s_client())?;
let era = generate_new_era();
let indexer_image_tag = create
.indexer_image_tag
.or(Some(create.validator_image_tag.clone()))
.expect("Expected indexer or validator image tag to use");
let config: Value = serde_json::from_value(json!({
"profile": DEFAULT_FORGE_DEPLOYER_PROFILE.to_string(),
"era": era.clone(),
"namespace": create.namespace.clone(),
"indexer-grpc-values": {
"indexerGrpcImage": format!("{}:{}", INDEXER_GRPC_DOCKER_IMAGE_REPO, &indexer_image_tag),
"fullnodeConfig": {
"image": format!("{}:{}", VALIDATOR_DOCKER_IMAGE_REPO, &indexer_image_tag),
}
},
}))?;

runtime.block_on(install_testnet_resources(
resize.namespace,
resize.num_validators,
resize.num_fullnodes,
resize.validator_image_tag,
resize.testnet_image_tag,
resize.move_modules_dir,
!resize.connect_directly,
resize.enable_haproxy,
era.clone(),
create.namespace.clone(),
create.num_validators,
create.num_fullnodes,
create.validator_image_tag,
create.testnet_image_tag,
create.move_modules_dir,
false, // since we skip_collecting_running_nodes, we don't connect directly to the nodes to validatet their health
create.enable_haproxy,
create.enable_indexer,
None,
None,
true,
))?;

if create.enable_indexer {
let indexer_deployer = ForgeDeployerManager::new(
kube_client.clone(),
create.namespace.clone(),
FORGE_INDEXER_DEPLOYER_DOCKER_IMAGE_REPO.to_string(),
None,
);
runtime.block_on(indexer_deployer.start(config))?;
runtime.block_on(indexer_deployer.wait_completed())?;
}
Ok(())
},
},
Expand Down
10 changes: 9 additions & 1 deletion testsuite/forge.py
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,8 @@ def run(self, context: ForgeContext) -> ForgeResult:
MULTIREGION_KUBECONFIG_DIR=MULTIREGION_KUBECONFIG_DIR,
)

log.info(f"rendered_forge_test_runner: {rendered}")

with ForgeResult.with_context(context) as forge_result:
specfile = context.filesystem.mkstemp()
context.filesystem.write(specfile, rendered.encode())
Expand Down Expand Up @@ -1147,6 +1149,7 @@ def create_forge_command(
forge_namespace_reuse: Optional[str],
forge_namespace_keep: Optional[str],
forge_enable_haproxy: Optional[str],
forge_enable_indexer: Optional[str],
cargo_args: Optional[Sequence[str]],
forge_cli_args: Optional[Sequence[str]],
test_args: Optional[Sequence[str]],
Expand Down Expand Up @@ -1216,6 +1219,8 @@ def create_forge_command(
forge_args.append("--keep")
if forge_enable_haproxy == "true":
forge_args.append("--enable-haproxy")
if forge_enable_indexer == "true":
forge_args.append("--enable-indexer")

if test_args:
forge_args.extend(test_args)
Expand Down Expand Up @@ -1328,6 +1333,7 @@ def seeded_random_choice(namespace: str, cluster_names: Sequence[str]) -> str:
@envoption("FORGE_NAMESPACE_KEEP")
@envoption("FORGE_NAMESPACE_REUSE")
@envoption("FORGE_ENABLE_HAPROXY")
@envoption("FORGE_ENABLE_INDEXER")
@envoption("FORGE_ENABLE_FAILPOINTS")
@envoption("FORGE_ENABLE_PERFORMANCE")
@envoption("FORGE_TEST_SUITE")
Expand Down Expand Up @@ -1373,6 +1379,7 @@ def test(
forge_enable_failpoints: Optional[str],
forge_enable_performance: Optional[str],
forge_enable_haproxy: Optional[str],
forge_enable_indexer: Optional[str],
forge_test_suite: str,
forge_runner_duration_secs: str,
forge_image_tag: Optional[str],
Expand Down Expand Up @@ -1598,12 +1605,13 @@ def test(
forge_namespace_reuse=forge_namespace_reuse,
forge_namespace_keep=forge_namespace_keep,
forge_enable_haproxy=forge_enable_haproxy,
forge_enable_indexer=forge_enable_indexer,
cargo_args=cargo_args,
forge_cli_args=forge_cli_args,
test_args=test_args,
)

log.debug("forge_args: %s", forge_args)
log.info("forge_args: %s", forge_args)

# use the github actor username if possible
forge_username = os.getenv("GITHUB_ACTOR") or "unknown-username"
Expand Down
3 changes: 3 additions & 0 deletions testsuite/forge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ thiserror = { workspace = true }
tokio = { workspace = true }
url = { workspace = true }

[dev-dependencies]
serde_merge = { workspace = true }

[features]
default = []
testing = ["aptos-global-constants/testing"]
Loading
Loading