Skip to content

Commit 6183a21

Browse files
committed
task: harden CI testing
1 parent 238c2cb commit 6183a21

14 files changed

Lines changed: 524 additions & 72 deletions
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
usage() {
5+
cat <<'EOF'
6+
Usage: prepare-unity-editmode-test-project.sh \
7+
--project-path <path> \
8+
--package-name <name> \
9+
--package-path <path> \
10+
--runtime-assembly <assembly-name>
11+
EOF
12+
}
13+
14+
project_path=""
15+
package_name=""
16+
package_path=""
17+
runtime_assembly=""
18+
19+
while [[ $# -gt 0 ]]; do
20+
case "$1" in
21+
--project-path)
22+
project_path="$2"
23+
shift 2
24+
;;
25+
--package-name)
26+
package_name="$2"
27+
shift 2
28+
;;
29+
--package-path)
30+
package_path="$2"
31+
shift 2
32+
;;
33+
--runtime-assembly)
34+
runtime_assembly="$2"
35+
shift 2
36+
;;
37+
-h|--help)
38+
usage
39+
exit 0
40+
;;
41+
*)
42+
echo "Unknown argument: $1" >&2
43+
usage >&2
44+
exit 2
45+
;;
46+
esac
47+
done
48+
49+
if [[ -z "$project_path" || -z "$package_name" || -z "$package_path" || -z "$runtime_assembly" ]]; then
50+
usage >&2
51+
exit 2
52+
fi
53+
54+
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
55+
repo_root="$(cd "$script_dir/../../.." && pwd)"
56+
template_root="$repo_root/.assets/ci/unity-editmode-tests"
57+
58+
if [[ ! -d "$template_root" ]]; then
59+
echo "Unity EditMode test template was not found: $template_root" >&2
60+
exit 1
61+
fi
62+
63+
rm -rf "$project_path"
64+
mkdir -p "$project_path"
65+
cp -R "$template_root/." "$project_path/"
66+
67+
mkdir -p "$project_path/Assets/Tests/EditMode"
68+
mkdir -p "$project_path/Assets/Tests/Runtime"
69+
cp "$repo_root"/Tests/EditMode/*.cs "$project_path/Assets/Tests/EditMode/"
70+
cp "$repo_root"/Tests/Runtime/*.cs "$project_path/Assets/Tests/Runtime/"
71+
72+
escape_sed_replacement() {
73+
printf '%s' "$1" | sed -e 's/[\/&|]/\\&/g'
74+
}
75+
76+
render_template() {
77+
local template_path="$1"
78+
local output_path="${template_path%.template}"
79+
80+
sed \
81+
-e "s|__PACKAGE_NAME__|$(escape_sed_replacement "$package_name")|g" \
82+
-e "s|__PACKAGE_PATH__|$(escape_sed_replacement "$package_path")|g" \
83+
-e "s|__RUNTIME_ASSEMBLY__|$(escape_sed_replacement "$runtime_assembly")|g" \
84+
"$template_path" > "$output_path"
85+
86+
rm "$template_path"
87+
}
88+
89+
render_template "$project_path/Assets/Tests/Runtime/FixedMathSharp.Unity.Tests.Runtime.asmdef.template"
90+
render_template "$project_path/Assets/Tests/EditMode/FixedMathSharp.Unity.Tests.EditMode.asmdef.template"
91+
render_template "$project_path/Packages/manifest.json.template"
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
usage() {
5+
cat <<'EOF'
6+
Usage: prepare-unity-sample-import-smoke.sh \
7+
--project-path <path> \
8+
--package-name <name> \
9+
--package-path <path> \
10+
--expected-sample-asmdef <file-name> \
11+
--workspace-path <path-visible-to-unity> \
12+
--git-sha <sha>
13+
EOF
14+
}
15+
16+
project_path=""
17+
package_name=""
18+
package_path=""
19+
expected_sample_asmdef=""
20+
workspace_path=""
21+
git_sha=""
22+
23+
while [[ $# -gt 0 ]]; do
24+
case "$1" in
25+
--project-path)
26+
project_path="$2"
27+
shift 2
28+
;;
29+
--package-name)
30+
package_name="$2"
31+
shift 2
32+
;;
33+
--package-path)
34+
package_path="$2"
35+
shift 2
36+
;;
37+
--expected-sample-asmdef)
38+
expected_sample_asmdef="$2"
39+
shift 2
40+
;;
41+
--workspace-path)
42+
workspace_path="$2"
43+
shift 2
44+
;;
45+
--git-sha)
46+
git_sha="$2"
47+
shift 2
48+
;;
49+
-h|--help)
50+
usage
51+
exit 0
52+
;;
53+
*)
54+
echo "Unknown argument: $1" >&2
55+
usage >&2
56+
exit 2
57+
;;
58+
esac
59+
done
60+
61+
if [[ -z "$project_path" || -z "$package_name" || -z "$package_path" || -z "$expected_sample_asmdef" || -z "$workspace_path" || -z "$git_sha" ]]; then
62+
usage >&2
63+
exit 2
64+
fi
65+
66+
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
67+
repo_root="$(cd "$script_dir/../../.." && pwd)"
68+
template_root="$repo_root/.assets/ci/unity-sample-import-smoke"
69+
70+
if [[ ! -d "$template_root" ]]; then
71+
echo "Unity sample import smoke template was not found: $template_root" >&2
72+
exit 1
73+
fi
74+
75+
rm -rf "$project_path"
76+
mkdir -p "$project_path"
77+
cp -R "$template_root/." "$project_path/"
78+
79+
if [[ "$workspace_path" == /* ]]; then
80+
package_url="git+file://${workspace_path}?path=/${package_path}#${git_sha}"
81+
else
82+
package_url="git+file:///${workspace_path}?path=/${package_path}#${git_sha}"
83+
fi
84+
85+
escape_sed_replacement() {
86+
printf '%s' "$1" | sed -e 's/[\/&|]/\\&/g'
87+
}
88+
89+
sed \
90+
-e "s|__PACKAGE_NAME__|$(escape_sed_replacement "$package_name")|g" \
91+
-e "s|__PACKAGE_URL__|$(escape_sed_replacement "$package_url")|g" \
92+
"$project_path/Packages/manifest.json.template" > "$project_path/Packages/manifest.json"
93+
94+
rm "$project_path/Packages/manifest.json.template"
95+
96+
sed \
97+
-e "s|__PACKAGE_NAME__|$(escape_sed_replacement "$package_name")|g" \
98+
-e "s|__EXPECTED_SAMPLE_ASMDEF__|$(escape_sed_replacement "$expected_sample_asmdef")|g" \
99+
"$project_path/Assets/FixedMathSharpSampleImportSmokeConfig.json.template" > "$project_path/Assets/FixedMathSharpSampleImportSmokeConfig.json"
100+
101+
rm "$project_path/Assets/FixedMathSharpSampleImportSmokeConfig.json.template"
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
if [[ $# -ne 1 ]]; then
5+
echo "Usage: scan-unity-sample-import-log.sh <editmode-log-path>" >&2
6+
exit 2
7+
fi
8+
9+
log_file="$1"
10+
if [[ ! -f "$log_file" ]]; then
11+
echo "Unity editmode log was not found: $log_file" >&2
12+
artifact_dir="$(dirname "$log_file")"
13+
find "$artifact_dir" -maxdepth 3 -type f -print 2>/dev/null || true
14+
exit 1
15+
fi
16+
17+
if ! grep -F "FMS_SAMPLE_SMOKE imported sample" "$log_file" > /dev/null; then
18+
echo "Sample import marker was not found in $log_file" >&2
19+
exit 1
20+
fi
21+
22+
bad_patterns=(
23+
"A meta data file (.meta) exists but its folder"
24+
"Assembly with name"
25+
"conflicting GUID"
26+
"DirectoryNotFoundException"
27+
"Samples~.meta"
28+
"Package add failed"
29+
"Scripts have compiler errors"
30+
"Compilation failed"
31+
"error CS"
32+
)
33+
34+
found_bad_pattern=0
35+
for pattern in "${bad_patterns[@]}"; do
36+
if grep -F -n "$pattern" "$log_file"; then
37+
found_bad_pattern=1
38+
fi
39+
done
40+
41+
if [[ "$found_bad_pattern" -ne 0 ]]; then
42+
echo "Known sample import failure pattern found in $log_file" >&2
43+
exit 1
44+
fi
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "FixedMathSharp.Unity.Tests.EditMode",
3+
"references": [
4+
"__RUNTIME_ASSEMBLY__",
5+
"FixedMathSharp.Unity.Tests.Runtime",
6+
"UnityEngine.TestRunner",
7+
"UnityEditor.TestRunner"
8+
],
9+
"includePlatforms": [
10+
"Editor"
11+
],
12+
"excludePlatforms": [],
13+
"allowUnsafeCode": false,
14+
"overrideReferences": true,
15+
"precompiledReferences": [
16+
"nunit.framework.dll",
17+
"FixedMathSharp.dll"
18+
],
19+
"autoReferenced": false,
20+
"defineConstraints": [
21+
"UNITY_INCLUDE_TESTS"
22+
],
23+
"versionDefines": []
24+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "FixedMathSharp.Unity.Tests.Runtime",
3+
"references": [
4+
"__RUNTIME_ASSEMBLY__"
5+
],
6+
"includePlatforms": [],
7+
"excludePlatforms": [],
8+
"allowUnsafeCode": false,
9+
"overrideReferences": false,
10+
"precompiledReferences": [],
11+
"autoReferenced": false,
12+
"defineConstraints": [
13+
"UNITY_INCLUDE_TESTS"
14+
],
15+
"versionDefines": [],
16+
"noEngineReferences": false
17+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"dependencies": {
3+
"__PACKAGE_NAME__": "file:../../../__PACKAGE_PATH__",
4+
"com.unity.modules.physics": "1.0.0",
5+
"com.unity.test-framework": "1.6.0"
6+
}
7+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
m_EditorVersion: 6000.3.9f1
2+
m_EditorVersionWithRevision: 6000.3.9f1 (7a9955a4f2fa)
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using System;
2+
using System.IO;
3+
using System.Linq;
4+
using UnityEditor;
5+
using UnityEditor.PackageManager.UI;
6+
7+
[InitializeOnLoad]
8+
internal static class FixedMathSharpSampleImportSmokeBootstrap
9+
{
10+
private const string ConfigAssetPath = "FixedMathSharpSampleImportSmokeConfig.json";
11+
private const string SampleDisplayName = "Demo Scene";
12+
private const string ImportedPathKey = "FixedMathSharp.SampleImportSmoke.ImportedPath";
13+
private const string ImportAttemptedKey = "FixedMathSharp.SampleImportSmoke.ImportAttempted";
14+
15+
static FixedMathSharpSampleImportSmokeBootstrap()
16+
{
17+
if (!ImportSampleOnce())
18+
EditorApplication.delayCall += () => ImportSampleOnce();
19+
}
20+
21+
private static bool ImportSampleOnce()
22+
{
23+
if (SessionState.GetBool(ImportAttemptedKey, false))
24+
return true;
25+
26+
if (!TryLoadConfig(out var config))
27+
{
28+
SessionState.SetBool(ImportAttemptedKey, true);
29+
return true;
30+
}
31+
32+
var packageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssetPath($"Packages/{config.packageName}/package.json");
33+
if (packageInfo == null)
34+
{
35+
UnityEngine.Debug.Log($"FMS_SAMPLE_SMOKE package not ready yet: {config.packageName}");
36+
return false;
37+
}
38+
39+
var sample = Sample.FindByPackage(packageInfo.name, packageInfo.version)
40+
.FirstOrDefault(candidate => string.Equals(candidate.displayName, SampleDisplayName, StringComparison.Ordinal));
41+
if (string.IsNullOrEmpty(sample.displayName))
42+
{
43+
UnityEngine.Debug.LogError($"FMS_SAMPLE_SMOKE sample was not found: {SampleDisplayName}");
44+
SessionState.SetBool(ImportAttemptedKey, true);
45+
return true;
46+
}
47+
48+
UnityEngine.Debug.Log($"FMS_SAMPLE_SMOKE importing {sample.displayName} from {sample.resolvedPath}");
49+
sample.Import(Sample.ImportOptions.OverridePreviousImports);
50+
SessionState.SetString(ImportedPathKey, sample.importPath);
51+
SessionState.SetBool(ImportAttemptedKey, true);
52+
AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
53+
UnityEngine.Debug.Log($"FMS_SAMPLE_SMOKE imported sample to {sample.importPath}");
54+
return true;
55+
}
56+
57+
private static bool TryLoadConfig(out SmokeConfig config)
58+
{
59+
config = null;
60+
61+
var configPath = Path.Combine(UnityEngine.Application.dataPath, ConfigAssetPath);
62+
if (!File.Exists(configPath))
63+
{
64+
UnityEngine.Debug.LogError($"FMS_SAMPLE_SMOKE config was not found: {configPath}");
65+
return false;
66+
}
67+
68+
config = UnityEngine.JsonUtility.FromJson<SmokeConfig>(File.ReadAllText(configPath));
69+
if (config == null || string.IsNullOrWhiteSpace(config.packageName))
70+
{
71+
UnityEngine.Debug.LogError($"FMS_SAMPLE_SMOKE config must define packageName: {configPath}");
72+
return false;
73+
}
74+
75+
return true;
76+
}
77+
78+
[Serializable]
79+
private sealed class SmokeConfig
80+
{
81+
public string packageName;
82+
}
83+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"packageName": "__PACKAGE_NAME__",
3+
"expectedSampleAsmdef": "__EXPECTED_SAMPLE_ASMDEF__"
4+
}

0 commit comments

Comments
 (0)