Skip to content

Commit

Permalink
Merge pull request #110 from codex-storage/feature/release-tests-cleanup
Browse files Browse the repository at this point in the history
Release tests cleanup
  • Loading branch information
benbierens authored Nov 29, 2024
2 parents 10b0136 + 58ed7ad commit 694b16f
Show file tree
Hide file tree
Showing 63 changed files with 1,251 additions and 128 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/run-continuous-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ env:
TESTS_TARGET_DURATION: 2d
TESTS_FILTER: ""
TESTS_CLEANUP: true
JOB_MANIFEST: docker/continuous-tests-job.yaml
JOB_MANIFEST: docker/job-continuous-tests.yaml
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
KUBE_VERSION: v1.28.2

Expand Down Expand Up @@ -146,7 +146,7 @@ jobs:
if: false
run: |
# Variables
# We need more than 300 seconds because Auto Scaler may take 3 minutes to tun a node
# We need more than 300 seconds because Auto Scaler may take 3 minutes to run a node
duration=600
namespace="${{ env.NAMESPACE }}"
pod=$(kubectl get pod --selector job-name=${{ env.NAMEPREFIX }} -o jsonpath="{.items[0].metadata.name}")
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-dist-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ env:
NAMEPREFIX: d-tests-runner
NAMESPACE: default
COMMAND: dotnet test Tests/CodexTests
JOB_MANIFEST: docker/dist-tests-job.yaml
JOB_MANIFEST: docker/job-dist-tests.yaml
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
KUBE_VERSION: v1.28.2

Expand Down
105 changes: 105 additions & 0 deletions .github/workflows/run-release-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Run Release Tests


on:
workflow_dispatch:
inputs:
codexdockerimage:
description: "Codex Docker image (example: 'codexstorage/nim-codex:0.1.8-dist-tests')"
required: true
type: string
workflow_call:
inputs:
codexdockerimage:
description: "Codex Docker image (example: 'codexstorage/nim-codex:0.1.8-dist-tests')"
required: true
type: string


env:
SOURCE: ${{ format('{0}/{1}', github.server_url, github.repository) }}
BRANCH: ${{ github.ref_name }}
CODEXDOCKERIMAGE: codexstorage/nim-codex:latest-dist-tests
TEST_TYPE: release-tests
NAMEPREFIX: r-tests
NAMESPACE: default
JOB_MANIFEST: docker/job-release-tests.yaml
COMMAND: dotnet test Tests/CodexReleaseTests
DURATION: 7200
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
KUBE_VERSION: v1.30.5


jobs:
run_tests:
name: Run Release Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
repository: ${{ inputs.workflow_source }}

- name: Variables
run: |
RUNID=$(date +%Y%m%d-%H%M%S)
echo "RUNID=${RUNID}" >> $GITHUB_ENV
echo "TESTID=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
[[ -n "${{ inputs.source }}" ]] && echo "SOURCE=${{ inputs.source }}" >>"$GITHUB_ENV" || echo "SOURCE=${{ env.SOURCE }}" >>"$GITHUB_ENV"
[[ -n "${{ inputs.branch }}" ]] && echo "BRANCH=${{ inputs.branch }}" >>"$GITHUB_ENV" || echo "BRANCH=${{ env.BRANCH }}" >>"$GITHUB_ENV"
[[ -n "${{ inputs.codexdockerimage }}" ]] && echo "CODEXDOCKERIMAGE=${{ inputs.codexdockerimage }}" >>"$GITHUB_ENV" || echo "CODEXDOCKERIMAGE=${{ env.CODEXDOCKERIMAGE }}" >>"$GITHUB_ENV"
[[ -n "${{ inputs.nameprefix }}" ]] && NAMEPREFIX="`awk '{ print tolower($0) }' <<< ${{ inputs.nameprefix }}`" || NAMEPREFIX="`awk '{ print tolower($0) }' <<< ${{ env.NAMEPREFIX }}`"
echo "NAMEPREFIX=${NAMEPREFIX}-${RUNID}" >>"$GITHUB_ENV"
[[ -n "${{ inputs.namespace }}" ]] && echo "NAMESPACE=${{ inputs.namespace }}" >>"$GITHUB_ENV" || echo "NAMESPACE=${{ env.NAMESPACE }}" >>"$GITHUB_ENV"
[[ -n "${{ inputs.command }}" ]] && COMMAND="${{ inputs.command }}" || COMMAND="${{ env.COMMAND }}"
echo "COMMAND=$(jq -c 'split(" ")' <<< '"'${COMMAND}'"')" >>"$GITHUB_ENV"
- name: Kubectl - Install ${{ env.KUBE_VERSION }}
uses: azure/setup-kubectl@v4
with:
version: ${{ env.KUBE_VERSION }}

- name: Kubectl - Kubeconfig
run: |
mkdir -p "${HOME}"/.kube
echo "${{ env.KUBE_CONFIG }}" | base64 -d > "${HOME}"/.kube/config
- name: Kubectl - Create Job to run tests
run: |
envsubst < ${{ env.JOB_MANIFEST }} | kubectl apply -f -
- name: Tests Identification
run: |
echo "----"
echo "Repository: ${{ env.SOURCE }}"
echo "Branch: ${{ env.BRANCH }}"
echo "Runner job: ${{ env.NAMEPREFIX }}"
echo "Runner pod: $(kubectl get pod --selector job-name=${{ env.NAMEPREFIX }} -ojsonpath='{.items[0].metadata.name}')"
echo "Runner namespace: ${{ env.NAMESPACE }}"
echo "----"
- name: Show Runner logs
run: |
# Variables
# We need more than 300 seconds because Auto Scaler may take 3 minutes to tun a node
duration=${{ env.DURATION }}
namespace="${{ env.NAMESPACE }}"
pod=$(kubectl get pod --selector job-name=${{ env.NAMEPREFIX }} -o jsonpath="{.items[0].metadata.name}")
# Check Pod status
WAIT=120
SECONDS=0
sleep=1
while (( SECONDS < WAIT )); do
phase=$(kubectl get pod ${pod} -n ${namespace} -o jsonpath="{.status.phase}")
[[ "${phase}" == "Running" ]] && { echo "Pod $pod is in $phase state - Get the logs"; break; } || { echo "Pod $pod is in $phase state - Retry in $sleep seconds / $((WAIT - SECONDS))"; }
sleep $sleep
done
# Get logs
timeout $duration \
kubectl logs $pod \
-n $namespace \
-f \
--tail=-1 \
--timestamps || true
14 changes: 13 additions & 1 deletion Framework/GethConnector/GethConnector.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CodexContractsPlugin;
using CodexContractsPlugin.Marketplace;
using GethPlugin;
using Logging;

Expand All @@ -18,18 +19,29 @@ public class GethConnector
return null;
}

var gethNode = new CustomGethNode(log, GethInput.GethHost, GethInput.GethPort, GethInput.PrivateKey);

var config = GetCodexMarketplaceConfig(gethNode, GethInput.MarketplaceAddress);

var contractsDeployment = new CodexContractsDeployment(
config: config,
marketplaceAddress: GethInput.MarketplaceAddress,
abi: GethInput.ABI,
tokenAddress: GethInput.TokenAddress
);

var gethNode = new CustomGethNode(log, GethInput.GethHost, GethInput.GethPort, GethInput.PrivateKey);
var contracts = new CodexContractsAccess(log, gethNode, contractsDeployment);

return new GethConnector(gethNode, contracts);
}

private static MarketplaceConfig GetCodexMarketplaceConfig(IGethNode gethNode, string marketplaceAddress)
{
var func = new ConfigurationFunctionBase();
var response = gethNode.Call<ConfigurationFunctionBase, ConfigurationOutputDTO>(marketplaceAddress, func);
return response.ReturnValue1;
}

private GethConnector(IGethNode gethNode, ICodexContracts codexContracts)
{
GethNode = gethNode;
Expand Down
11 changes: 11 additions & 0 deletions ProjectPlugins/CodexContractsPlugin/CodexContractsAccess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using GethPlugin;
using Logging;
using Nethereum.ABI;
using Nethereum.Hex.HexConvertors.Extensions;
using Nethereum.Util;
using NethereumWorkflow;
using Newtonsoft.Json;
Expand All @@ -24,6 +25,7 @@ public interface ICodexContracts
ICodexContractsEvents GetEvents(BlockInterval blockInterval);
EthAddress? GetSlotHost(Request storageRequest, decimal slotIndex);
RequestState GetRequestState(Request request);
void WaitUntilNextPeriod();
}

[JsonConverter(typeof(StringEnumConverter))]
Expand Down Expand Up @@ -114,6 +116,15 @@ public RequestState GetRequestState(Request request)
return gethNode.Call<RequestStateFunction, RequestState>(Deployment.MarketplaceAddress, func);
}

public void WaitUntilNextPeriod()
{
log.Log("Waiting until next proof period...");
var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
var periodSeconds = (int)Deployment.Config.Proofs.Period;
var secondsLeft = now % periodSeconds;
Thread.Sleep(TimeSpan.FromSeconds(secondsLeft + 1));
}

private ContractInteractions StartInteraction()
{
return new ContractInteractions(log, gethNode);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
namespace CodexContractsPlugin
using CodexContractsPlugin.Marketplace;

namespace CodexContractsPlugin
{
public class CodexContractsDeployment
{
public CodexContractsDeployment(string marketplaceAddress, string abi, string tokenAddress)
public CodexContractsDeployment(MarketplaceConfig config, string marketplaceAddress, string abi, string tokenAddress)
{
Config = config;
MarketplaceAddress = marketplaceAddress;
Abi = abi;
TokenAddress = tokenAddress;
}

public MarketplaceConfig Config { get; }
public string MarketplaceAddress { get; }
public string Abi { get; }
public string TokenAddress { get; }
Expand Down
17 changes: 15 additions & 2 deletions ProjectPlugins/CodexContractsPlugin/CodexContractsStarter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using KubernetesWorkflow;
using KubernetesWorkflow.Types;
using Logging;
using Newtonsoft.Json;
using Utils;

namespace CodexContractsPlugin
Expand Down Expand Up @@ -34,6 +35,7 @@ public CodexContractsDeployment Deploy(CoreInterface ci, IGethNode gethNode)
try
{
var result = DeployContract(container, workflow, gethNode);

workflow.Stop(containers, waitTillStopped: false);
Log("Container stopped.");
return result;
Expand Down Expand Up @@ -75,9 +77,20 @@ private CodexContractsDeployment DeployContract(RunningContainer container, ISta

Time.WaitUntil(() => interaction.IsSynced(marketplaceAddress, abi), nameof(DeployContract));

Log("Synced. Codex SmartContracts deployed.");
Log("Synced. Codex SmartContracts deployed. Getting configuration...");

var config = GetMarketplaceConfiguration(marketplaceAddress, gethNode);

Log("Got config: " + JsonConvert.SerializeObject(config));

return new CodexContractsDeployment(marketplaceAddress, abi, tokenAddress);
return new CodexContractsDeployment(config, marketplaceAddress, abi, tokenAddress);
}

private MarketplaceConfig GetMarketplaceConfiguration(string marketplaceAddress, IGethNode gethNode)
{
var func = new ConfigurationFunctionBase();
var response = gethNode.Call<ConfigurationFunctionBase, ConfigurationOutputDTO>(marketplaceAddress, func);
return response.ReturnValue1;
}

private void EnsureCompatbility(string abi, string bytecode)
Expand Down
10 changes: 2 additions & 8 deletions ProjectPlugins/CodexContractsPlugin/ContractInteractions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ public ContractInteractions(ILog log, IGethNode gethNode)
public string GetTokenAddress(string marketplaceAddress)
{
log.Debug(marketplaceAddress);
var function = new GetTokenFunction();

return gethNode.Call<GetTokenFunction, string>(marketplaceAddress, function);
var function = new TokenFunctionBase();
return gethNode.Call<TokenFunctionBase, string>(marketplaceAddress, function);
}

public string GetTokenName(string tokenAddress)
Expand Down Expand Up @@ -111,11 +110,6 @@ private bool IsContractAvailable(string marketplaceAddress, string marketplaceAb
}
}

[Function("token", "address")]
public class GetTokenFunction : FunctionMessage
{
}

[Function("name", "string")]
public class GetTokenNameFunction : FunctionMessage
{
Expand Down
10 changes: 10 additions & 0 deletions ProjectPlugins/CodexContractsPlugin/TestTokenExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ public override string ToString()
return new TestToken(a.TstWei + b.TstWei);
}

public static TestToken operator -(TestToken a, TestToken b)
{
return new TestToken(a.TstWei - b.TstWei);
}

public static TestToken operator *(TestToken a, int b)
{
return new TestToken(a.TstWei * b);
}

public static bool operator <(TestToken a, TestToken b)
{
return a.TstWei < b.TstWei;
Expand Down
28 changes: 28 additions & 0 deletions ProjectPlugins/CodexPlugin/CodexAccess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ public DebugInfo GetDebugInfo()
return mapper.Map(OnCodex(api => api.GetDebugInfoAsync()));
}

public string GetSpr()
{
return CrashCheck(() =>
{
var endpoint = GetEndpoint();
var json = endpoint.HttpGetString("spr");
var response = JsonConvert.DeserializeObject<SprResponse>(json);
return response!.Spr;
});
}

private class SprResponse
{
public string Spr { get; set; } = string.Empty;
}

public DebugPeer GetDebugPeer(string peerId)
{
// Cannot use openAPI: debug/peer endpoint is not specified there.
Expand Down Expand Up @@ -80,6 +96,18 @@ public Stream DownloadFile(string contentId, Action<Failure> onFailure)
return fileResponse.Stream;
}

public LocalDataset DownloadStreamless(ContentId cid)
{
var response = OnCodex(api => api.DownloadNetworkAsync(cid.Id));
return mapper.Map(response);
}

public LocalDataset DownloadManifestOnly(ContentId cid)
{
var response = OnCodex(api => api.DownloadNetworkManifestAsync(cid.Id));
return mapper.Map(response);
}

public LocalDatasetList LocalFiles()
{
return mapper.Map(OnCodex(api => api.ListDataAsync()));
Expand Down
18 changes: 18 additions & 0 deletions ProjectPlugins/CodexPlugin/CodexNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ public interface ICodexNode : IHasContainer, IHasMetricsScrapeTarget, IHasEthAdd
string GetName();
string GetPeerId();
DebugInfo GetDebugInfo();
string GetSpr();
DebugPeer GetDebugPeer(string peerId);
ContentId UploadFile(TrackedFile file);
ContentId UploadFile(TrackedFile file, Action<Failure> onFailure);
ContentId UploadFile(TrackedFile file, string contentType, string contentDisposition, Action<Failure> onFailure);
TrackedFile? DownloadContent(ContentId contentId, string fileLabel = "");
TrackedFile? DownloadContent(ContentId contentId, Action<Failure> onFailure, string fileLabel = "");
LocalDataset DownloadStreamless(ContentId cid);
LocalDataset DownloadManifestOnly(ContentId cid);
LocalDatasetList LocalFiles();
CodexSpace Space();
void ConnectToPeer(ICodexNode node);
Expand Down Expand Up @@ -128,6 +131,11 @@ public DebugInfo GetDebugInfo()
return debugInfo;
}

public string GetSpr()
{
return CodexAccess.GetSpr();
}

public DebugPeer GetDebugPeer(string peerId)
{
return CodexAccess.GetDebugPeer(peerId);
Expand Down Expand Up @@ -192,6 +200,16 @@ public ContentId UploadFile(TrackedFile file, string contentType, string content
return file;
}

public LocalDataset DownloadStreamless(ContentId cid)
{
return CodexAccess.DownloadStreamless(cid);
}

public LocalDataset DownloadManifestOnly(ContentId cid)
{
return CodexAccess.DownloadManifestOnly(cid);
}

public LocalDatasetList LocalFiles()
{
return CodexAccess.LocalFiles();
Expand Down
Loading

0 comments on commit 694b16f

Please sign in to comment.