Files
Nim/tests/stdlib/tmarshalsegfault.nim
metagn a55c15c651 fix tmarshalsegfault depending on execution time (#24153)
Added in #24119, the test checks if every string produced is equal, but
the value of the strings depend on the `now()` timestamp of when they
were produced. 30 of them are produced in a for loop in sequence with
each other, but the first one is set after the data is marshalled into
and unmarshalled from a file. This means the timestamp strings can
differ depending on the execution time and causes this test to be flaky.
Instead we just make 2 strings from the same data and check if they
equal each other.
2024-09-22 13:57:03 +02:00

55 lines
1.7 KiB
Nim

# issue #12405
import std/[marshal, streams, times, tables, os, assertions]
type AiredEpisodeState * = ref object
airedAt * : DateTime
tvShowId * : string
seasonNumber * : int
number * : int
title * : string
type ShowsWatchlistState * = ref object
aired * : seq[AiredEpisodeState]
type UiState * = ref object
shows: ShowsWatchlistState
# Helpers to marshal and unmarshal
proc load * ( state : var UiState, file : string ) =
var strm = newFileStream( file, fmRead )
strm.load( state )
strm.close()
proc store * ( state : UiState, file : string ) =
var strm = newFileStream( file, fmWrite )
strm.store( state )
strm.close()
# 1. We fill the state initially
var state : UiState = UiState( shows: ShowsWatchlistState( aired: @[] ) )
# VERY IMPORTANT: For some reason, small numbers (like 2 or 3) don't trigger the bug. Anything above 7 or 8 on my machine triggers though
for i in 0..30:
var episode = AiredEpisodeState( airedAt: now(), tvShowId: "1", seasonNumber: 1, number: 1, title: "string" )
state.shows.aired.add( episode )
# 2. Store it in a file with the marshal module, and then load it back up
store( state, "tmarshalsegfault_data" )
load( state, "tmarshalsegfault_data" )
removeFile("tmarshalsegfault_data")
# 3. VERY IMPORTANT: Without this line, for some reason, everything works fine
state.shows.aired[ 0 ] = AiredEpisodeState( airedAt: now(), tvShowId: "1", seasonNumber: 1, number: 1, title: "string" )
# 4. And formatting the airedAt date will now trigger the exception
for ep in state.shows.aired:
let x = $ep.seasonNumber & "x" & $ep.number & " (" & $ep.airedAt & ")"
let y = $ep.seasonNumber & "x" & $ep.number & " (" & $ep.airedAt & ")"
doAssert x == y