Skip to content

Commit c227d5a

Browse files
committed
repo: try to setup tests
1 parent ccb306d commit c227d5a

File tree

8 files changed

+277
-3
lines changed

8 files changed

+277
-3
lines changed

.github/workflows/compile-ghostinj.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ on:
1010
workflow_dispatch:
1111

1212
jobs:
13-
build:
13+
build_ghostinj:
14+
name: "Build GhostInj"
1415
uses: RaphaelIT7/gmod-common-module-base/.github/workflows/compile.yml@workflow
1516
with:
1617
PROJECT_PATH: "ghostinj-dll/"

.github/workflows/compile.yml

Lines changed: 116 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ on:
1212
workflow_dispatch:
1313

1414
jobs:
15-
build:
15+
build_plugin:
16+
name: "Build Plugin"
1617
uses: RaphaelIT7/gmod-common-module-base/.github/workflows/compile.yml@workflow
1718
with:
1819
PROJECT_NAME: "holylib"
@@ -27,6 +28,7 @@ jobs:
2728
GARRYSMOD_COMMON: "RaphaelIT7/garrysmod_common"
2829

2930
build_testingarea:
31+
name: "Build 32x (Testing Area)"
3032
uses: RaphaelIT7/gmod-common-module-base/.github/workflows/compile.yml@workflow
3133
secrets:
3234
PTERODACTYL_KEY: ${{ secrets.PTERODACTYL_KEY }}
@@ -45,6 +47,7 @@ jobs:
4547
GARRYSMOD_COMMON: "RaphaelIT7/garrysmod_common"
4648

4749
build_testingarea_64x:
50+
name: "Build 64x (Testing Area)"
4851
uses: RaphaelIT7/gmod-common-module-base/.github/workflows/compile.yml@workflow
4952
secrets:
5053
PTERODACTYL_KEY: ${{ secrets.PTERODACTYL_KEY }}
@@ -61,4 +64,115 @@ jobs:
6164
SOURCESDK_MINIMAL: "RaphaelIT7/sourcesdk-minimal"
6265
SOURCESDK_MINIMAL_BRANCH: "patch-6"
6366
SOURCESDK_MINIMAL_64XBRANCH: "x86-64-patch-1"
64-
GARRYSMOD_COMMON: "RaphaelIT7/garrysmod_common"
67+
GARRYSMOD_COMMON: "RaphaelIT7/garrysmod_common"
68+
69+
build_ghostinj:
70+
name: "Build GhostInj"
71+
uses: RaphaelIT7/gmod-common-module-base/.github/workflows/compile.yml@workflow
72+
with:
73+
PROJECT_PATH: "ghostinj-dll/"
74+
PROJECT_NAME: "ghostinj"
75+
BUILD_64x: "true"
76+
LINUX_FILEEXTENTION: "dll"
77+
BUILD_WINDOWS: "false"
78+
USE_PREFIX: "false"
79+
ARTIFACT_EXPIRE: "1"
80+
81+
setup_32x_artifacts:
82+
name: "Setup 32x Artifact"
83+
needs: [build_plugin, build_ghostinj]
84+
runs-on: ubuntu-latest
85+
container: debian:bullseye
86+
steps:
87+
- uses: actions/download-artifact@v4
88+
name: "Download 32x plugin"
89+
with:
90+
name: "gmsv_holylib_linux.so"
91+
92+
- uses: actions/download-artifact@v4
93+
name: "Download 32x ghostinj"
94+
with:
95+
name: "ghostinj.dll"
96+
97+
- name: "Create structure"
98+
run: |
99+
mkdir -p garrysmod/lua/bin
100+
101+
ls -R
102+
103+
mv "ghostinj.dll/ghostinj.dll" ghostinj.dll
104+
mv "gmsv_holylib_linux.so/gmsv_holylib_linux.so" garrysmod/lua/bin/
105+
106+
rm -rf "gmsv_holylib_linux.so/"
107+
rm -rf "ghostinj.dll/"
108+
109+
zip -r gluatest.zip ghostinj.dll garrysmod/
110+
111+
- uses: actions/upload-artifact@v4
112+
name: "Upload zip"
113+
with:
114+
name: gluatest_32x
115+
path: gluatest.zip
116+
117+
setup_64x_artifacts:
118+
name: "Setup 64x Artifact"
119+
needs: [build_plugin, build_ghostinj]
120+
runs-on: ubuntu-latest
121+
container: debian:bullseye
122+
steps:
123+
- uses: actions/download-artifact@v4
124+
name: "Download 64x plugin"
125+
with:
126+
name: "gmsv_holylib_linux64.so (64x)"
127+
128+
- uses: actions/download-artifact@v4
129+
name: "Download 64x ghostinj"
130+
with:
131+
name: "ghostinj.dll (64x)"
132+
133+
- name: "Create structure"
134+
run: |
135+
mkdir -p garrysmod/lua/bin
136+
137+
ls -R
138+
139+
mv "ghostinj.dll (64x)/ghostinj.dll" ghostinj.dll
140+
mv "gmsv_holylib_linux64.so (64x)/gmsv_holylib_linux64.so" garrysmod/lua/bin/
141+
142+
rm -rf "gmsv_holylib_linux64.so (64x)/"
143+
rm -rf "ghostinj.dll (64x)/"
144+
145+
zip -r gluatest.zip ghostinj.dll garrysmod/
146+
147+
- uses: actions/upload-artifact@v4
148+
name: "Upload zip"
149+
with:
150+
name: gluatest_64x
151+
path: gluatest.zip
152+
153+
test_32bit_live:
154+
name: "Test live branch"
155+
needs: setup_32x_artifacts
156+
uses: RaphaelIT7/GLuaTest/.github/workflows/run_tests_runnerimprovements.yml@holylib
157+
with:
158+
branch: live
159+
gluatest-ref: "holylib"
160+
extra-startup-args: "-usegh"
161+
162+
test_32bit_dev:
163+
name: "Test dev branch"
164+
needs: setup_32x_artifacts
165+
uses: RaphaelIT7/GLuaTest/.github/workflows/run_tests_runnerimprovements.yml@holylib
166+
with:
167+
branch: dev
168+
gluatest-ref: "holylib"
169+
extra-startup-args: "-usegh"
170+
171+
test_64bit:
172+
name: "Test x86-64 branch"
173+
needs: setup_64x_artifacts
174+
uses: RaphaelIT7/GLuaTest/.github/workflows/run_tests_runnerimprovements.yml@holylib
175+
with:
176+
branch: x86-64
177+
gluatest-ref: "holylib"
178+
extra-startup-args: "-usegh"

gluatests/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# gluatests
2+
3+
Tests executed after a build was done.
4+
This is based off https://github.com/CFC-Servers/gmod_tests as it has a nice base.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include( "gmod_tests/sh_init.lua" )
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
-- Helpers and utilities for the gmod_tests test suite
2+
-- (TODO: Do these belong somewhere else)
3+
AddCSLuaFile()
4+
5+
WHEN_NO_HUMANS = function()
6+
return #player.GetHumans() == 0
7+
end
8+
9+
local jitVersion = jit.version
10+
IS_BASE_BRANCH = jitVersion == "LuaJIT 2.0.4"
11+
IS_64BIT_BRANCH = jitVersion == "LuaJIT 2.1.0-beta3"
12+
13+
-- NOTE: The names could be wrong. I took them from here: https://github.com/RaphaelIT7/obsolete-source-engine/blob/gmod/public/tier1/iconvar.h#L41
14+
FCVAR_DEVELOPMENTONLY = bit.lshift( 1, 1 )
15+
FCVAR_HIDDEN = bit.lshift( 1, 4 )
16+
FCVAR_INTERNAL_USE = bit.lshift( 1, 15 )
17+
FCVAR_RELOAD_MATERIALS = bit.lshift( 1, 20 )
18+
FCVAR_RELOAD_TEXTURES = bit.lshift( 1, 21 )
19+
FCVAR_MATERIAL_SYSTEM_THREAD = bit.lshift( 1, 23 )
20+
FCVAR_ACCESSIBLE_FROM_THREADS = bit.lshift( 1, 25 )
21+
FCVAR_AVAILABLE1 = bit.lshift( 1, 26 )
22+
FCVAR_AVAILABLE2 = bit.lshift( 1, 27 )
23+
24+
if SERVER then
25+
--- Makes an entity for test purposes
26+
--- @param class string? The class of the entity
27+
--- @param model string? The model of the entity
28+
--- @param shouldSpawn boolean? Whether the entity should be :Spawn()'d
29+
--- @param shouldFreeze boolean? Whether the entity should be :Freeze()'d (only valid if shouldSpawn is true)
30+
MakeTestEntity = function( class, model, shouldSpawn, shouldFreeze )
31+
shouldSpawn = shouldSpawn == true
32+
33+
local ent = ents.Create( class or "prop_physics" )
34+
ent:SetModel( model or "models/props_c17/oildrum001.mdl" )
35+
36+
if shouldSpawn then
37+
ent:Spawn()
38+
39+
if shouldFreeze then
40+
local physObj = ent:GetPhysicsObject()
41+
physObj:EnableMotion( false )
42+
end
43+
end
44+
45+
return ent
46+
end
47+
48+
local botCounter = 0
49+
--- Makes a bot for test purposes
50+
--- @param name string? The name of the bot
51+
MakeTestBot = function( name )
52+
botCounter = botCounter + 1
53+
54+
name = name or ("Bot " .. botCounter)
55+
return player.CreateNextBot( name )
56+
end
57+
58+
--- @class TestEntityConfig
59+
--- @field class string? The class of the entity
60+
--- @field model string? The model of the Entity
61+
--- @field shouldSpawn boolean? Whether the entity should be :Spawn()'d
62+
--- @field shouldFreeze boolean? Whether the entity should be :Freeze()'d (only valid if shouldSpawn is true)
63+
--- @field createdCallback fun(ent: Entity)? A callback to run after the entity is created
64+
65+
--- Sets up a testGroup to make a test ent for each test, and remove it after each test
66+
--- @param testGroup table The test group to modify
67+
--- @param config TestEntityConfig? The configuration for the test entity
68+
WithTestEntity = function( testGroup, config )
69+
config = config or {}
70+
71+
testGroup.beforeEach = function( state )
72+
state.ent = MakeTestEntity( config.class, config.model, config.shouldSpawn, config.shouldFreeze )
73+
74+
local cb = config.createdCallback
75+
if cb then cb( state.ent ) end
76+
end
77+
78+
testGroup.afterEach = function( state )
79+
SafeRemoveEntity( state.ent )
80+
end
81+
82+
return testGroup
83+
end
84+
85+
--- @class TestBotConfig
86+
--- @field name? string The name of the bot
87+
--- @field createdCallback fun(ply: Player)? A callback to run after the bot is created
88+
89+
--- Sets up a testGroup to make a test bot for each test, and remove it after each test
90+
--- @param testGroup table The test group to modify
91+
--- @param config TestBotConfig? The configuration for the test bot
92+
WithTestBot = function( testGroup, config )
93+
config = config or {}
94+
95+
testGroup.beforeEach = function( state )
96+
state.bot = MakeTestBot( config.name )
97+
98+
local cb = config.createdCallback
99+
if cb then cb( state.bot ) end
100+
end
101+
102+
testGroup.afterEach = function( state )
103+
local bot = state.bot
104+
105+
if not IsValid( bot ) then return end
106+
bot:Kick()
107+
end
108+
end
109+
end
110+
111+
-- Helper utility to isolate test groups
112+
-- If any test group has `yes = true`, then only test groups that have `yes = true` will be run
113+
hook.Add( "GLuaTest_StartedTestRun", "Yes", function( testGroups )
114+
local hasYes = false
115+
local groupCount = #testGroups
116+
117+
local toRemove = {}
118+
119+
for i = 1, groupCount do
120+
local group = testGroups[i]
121+
122+
if group.yes then
123+
hasYes = true
124+
else
125+
table.insert( toRemove, 1, i )
126+
end
127+
end
128+
129+
if not hasYes then return end
130+
131+
for _, i in ipairs( toRemove ) do
132+
table.remove( testGroups, i )
133+
end
134+
end )
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
return {
2+
groupName = "GetGlobalEntityList",
3+
cases = {
4+
--[[ Function Signature ]]--
5+
--#region
6+
{
7+
name = "Function exists globally",
8+
func = function()
9+
expect( GetGlobalEntityList ).to.beA( "function" )
10+
end
11+
},
12+
{
13+
name = "Returns an Table object",
14+
func = function()
15+
local entities = GetGlobalEntityList()
16+
expect( entities ).to.beA( "table" )
17+
end
18+
},
19+
}
20+
}

project/gluatest_custom.cfg

Whitespace-only changes.

project/gluatest_requirements.txt

Whitespace-only changes.

0 commit comments

Comments
 (0)