-
Notifications
You must be signed in to change notification settings - Fork 920
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
add testgen to generate test cases #1801
base: master
Are you sure you want to change the base?
Conversation
So how does this thing work? Do we need to run something afterward to make use of the test cases? |
The idea is we use $ sha1sum testdata/tiles_dlvl=1,quest_id=255,seed=123.bin
12a0410904ebf2507b6b7017f0ae191ae476686b testdata/tiles_dlvl=1,quest_id=255,seed=123.bin
$ sha1sum testdata/tiles_dlvl=2,quest_id=6,seed=123.bin
659b95eec3e1c18d13b7f9932de108b88b356b9b testdata/tiles_dlvl=2,quest_id=6,seed=123.bin Now, we create a test case in C++ using Google test or something like that, and essentially set up the pre-condition (i.e. the state of global variables) before calling I played around with this and implemented a PoC in Go. For reference, see https://github.com/sanctuary/djavul/blob/e1ed5212bc6e67e0bdf6270f5da1bb474fe1bf97/d1/l1/l1_testxxx.go#L33, a simplified extract of which is provided below: golden := []struct {
dungeonName string
dlvl int
dtype enum.DType
questID enum.QuestID
seed int32
wantTiles string
wantDPieces string
wantArches string
wantTransparency string
}{
{
dungeonName: "Cathedral",
dlvl: 1,
dtype: enum.DTypeCathedral,
questID: enum.QuestIDNone,
seed: 123,
wantTiles: "12a0410904ebf2507b6b7017f0ae191ae476686b",
wantDPieces: "e15a7afb7505cb01b0b3d1befce5b8d4833ae1c6",
wantArches: "5438e3d7761025a2ee6f7fec155c840fc289f5dd",
wantTransparency: "1269467cb381070f72bc6c8e69938e88da7e58cc",
},
...
{
dungeonName: "The Butcher",
dlvl: quests.QuestData[enum.QuestIDTheButcher].DLvlSingle,
dtype: enum.DTypeCathedral,
questID: enum.QuestIDTheButcher,
seed: 123,
wantTiles: "659b95eec3e1c18d13b7f9932de108b88b356b9b",
wantDPieces: "15f2209ff5d066cfd568a1eab77e4328d08474e8",
wantArches: "42941df3ada356ebf87ce2987d26a06c44da711a",
wantTransparency: "74c24e596ec57a91261bc3a559270f31d6811336",
},
}
multi.MaxPlayers = 1 // single player.
pass := true
for _, g := range golden {
// Establish pre-conditions.
gendung.DLvl = g.dlvl
gendung.DType = g.dtype
for i := range quests.Quests {
quests.Quests[i].QuestID = enum.QuestID(i)
quests.Quests[i].QuestState = 0
}
gendung.IsSetLevel = false
if g.questID != enum.QuestIDNone {
quests.Quests[g.questID].QuestState = 1
quests.Quests[g.questID].DLvl = g.dlvl
}
entry := int(0)
CreateDungeon(uint32(g.seed), entry)
if err := check(gendung.TileIDMap, "tiles", g.seed, g.wantTiles); err != nil {
// FAIL
pass = false
}
}
if !pass {
fmt.Println("test case failed")
} else {
fmt.Println("test case passed")
} Helper function to compute SHA1 hash: // check validates the data against the given SHA1 hashsum.
func check(data interface{}, name string, seed int32, want string) error {
buf := &bytes.Buffer{}
if err := binary.Write(buf, binary.LittleEndian, data); err != nil {
return errors.WithStack(err)
}
sum := sha1.Sum(buf.Bytes())
got := fmt.Sprintf("%040x", sum[:])
if got != want {
return errors.Errorf("SHA1 hash mismatch for %v, seed 0x%08X; expected %q, got %q", name, seed, want, got)
}
return nil
} |
Ok, so if I understand this correctly the goal is to provide a way for others to easily verify there important gains that of devilution, not to check devilution against vanilla? We should take care not to use the SHA1bad implementation 😅 |
Ideally, we would add this hook to the vanilla Diablo.exe executable, so we could get the ensured golden SHA1 hashes. Then adding test cases to Devilution would help ensure that we don't mess things up when doing future cleanups. Adding test cases to DevilutionX becomes especially important since DevilutionX seeks to do quite a few cleanups, any of which could change something subtle in how the DRLG works (e.g. signed vs. unsigned integers, 32- vs 64-bit integers, etc). |
Ok, I will be looking forward for part two then :) Really exciting that this can also be used with vanilla Diablo.exe |
Note, SHA1 hash of testdata/tiles_123.bin is correct for input seed 123. 12a0410904ebf2507b6b7017f0ae191ae476686b
This seed generates a dungeon with an opening into nothing at the end of the map.
Also, add dump_dun.sh script to convert DUN file to TMX format.
In other words, this test case checks that "Levels/L1Data/SKngDO.DUN" is loaded correctly on dungeon level 3. This raises test case coverage of d1/l1 from 88.3% to 88.6%.
This helps track when TMX maps need to be regenerated based on time stmaps.
Add all broken seeds from https://github.com/sanctuary/graphics/tree/master/l1/broken d1/l1 test coverage is now at 91%.
This takes d1/l1 test coverage from 91% to 91.3%.
@AJenbo should we close this PR now that DevilutionX has integrated test cases? |
My understanding was that this could be used to generate test data for the tests in DevilutionX. So I was thinking we keep this around until we have done so and implemented the tests for the dungeon generators (and verified it against original game exe). I'm currently seeing some issues with the Crypt levels in DevilutionX where save games appear to not match the original layout, but I haven't fully verified it yet. |
Usage:
Or run the
gen_tests.sh
script which runs the above commands:Edit: this Git history of this one is really hacky. So feel free to squash.