Skip to content
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

testutils: Add script-based test utilities #54

Merged
merged 1 commit into from
Sep 30, 2024
Merged

Conversation

joamaki
Copy link
Contributor

@joamaki joamaki commented Sep 17, 2024

Add testutils with functions for creating commands for testscript.

This allows implementing tests as scripts, which becomes useful when tests perform multiple steps and need to verify one or more tables on each step. This aims to be a better way of writing test-suites that work against a set of input files and golden output files.

Each test suite would define their own set of commands with some table-based ones built using the utils and perhaps some specific to the thing being tested.

testscript docs: https://pkg.go.dev/github.com/rogpeppe/go-internal/testscript
blog posts for better intro: https://encore.dev/blog/testscript-hidden-testing-gem, https://atlasgo.io/blog/2024/09/09/how-go-tests-go-test

and the reason I didn't use rsc.io/script: rsc/script#4

Copy link

github-actions bot commented Sep 17, 2024

$ make test
go: downloading golang.org/x/tools v0.17.0
go: downloading github.com/spf13/cast v1.6.0
go: downloading github.com/fsnotify/fsnotify v1.7.0
go: downloading github.com/sagikazarmark/slog-shim v0.1.0
go: downloading github.com/spf13/afero v1.11.0
go: downloading golang.org/x/sys v0.17.0
go: downloading github.com/subosito/gotenv v1.6.0
go: downloading github.com/hashicorp/hcl v1.0.0
go: downloading gopkg.in/ini.v1 v1.67.0
go: downloading github.com/magiconair/properties v1.8.7
go: downloading github.com/pelletier/go-toml/v2 v2.1.0
go: downloading golang.org/x/text v0.14.0
	github.com/cilium/statedb/reconciler/benchmark		coverage: 0.0% of statements
	github.com/cilium/statedb/reconciler/example		coverage: 0.0% of statements
ok  	github.com/cilium/statedb	6.418s	coverage: 83.7% of statements
ok  	github.com/cilium/statedb/index	0.006s	coverage: 44.6% of statements
ok  	github.com/cilium/statedb/internal	0.013s	coverage: 93.3% of statements
ok  	github.com/cilium/statedb/part	3.249s	coverage: 82.8% of statements
ok  	github.com/cilium/statedb/reconciler	2.561s	coverage: 92.9% of statements
ok  	github.com/cilium/statedb/testutils	0.007s	coverage: 79.1% of statements
-----
$ make bench
go test ./... -bench . -benchmem -test.run xxx
goos: linux
goarch: amd64
pkg: github.com/cilium/statedb
cpu: AMD EPYC 7763 64-Core Processor                
BenchmarkDB_WriteTxn_1-4                    	  460106	      2594 ns/op	    385569 objects/sec	    2800 B/op	      32 allocs/op
BenchmarkDB_WriteTxn_10-4                   	 1000000	      1002 ns/op	    998361 objects/sec	     742 B/op	      10 allocs/op
BenchmarkDB_WriteTxn_100-4                  	 1506156	       826.6 ns/op	   1209825 objects/sec	     593 B/op	       7 allocs/op
BenchmarkDB_WriteTxn_1000-4                 	 1437578	       828.5 ns/op	   1207032 objects/sec	     550 B/op	       7 allocs/op
BenchmarkDB_WriteTxn_100_SecondaryIndex-4   	  507788	      2274 ns/op	    439686 objects/sec	    1490 B/op	      37 allocs/op
BenchmarkDB_Modify-4                        	    1284	    947737 ns/op	   1055146 objects/sec	  766562 B/op	    8455 allocs/op
BenchmarkDB_GetInsert-4                     	    1178	   1037023 ns/op	    964300 objects/sec	  757419 B/op	    8461 allocs/op
BenchmarkDB_RandomInsert-4                  	    2282	    505479 ns/op	   1978322 objects/sec	  402223 B/op	    7097 allocs/op
BenchmarkDB_RandomReplace-4                 	     318	   3740056 ns/op	    267376 objects/sec	 2351305 B/op	   48575 allocs/op
BenchmarkDB_SequentialInsert-4              	    1467	    829004 ns/op	   1206267 objects/sec	  550805 B/op	    7285 allocs/op
BenchmarkDB_Changes_Baseline-4              	    1237	    960424 ns/op	   1041208 objects/sec	  553058 B/op	   10252 allocs/op
BenchmarkDB_Changes-4                       	     692	   1713259 ns/op	    583683 objects/sec	  993198 B/op	   14493 allocs/op
BenchmarkDB_RandomLookup-4                  	   22292	     53460 ns/op	  18705532 objects/sec	     144 B/op	       1 allocs/op
BenchmarkDB_SequentialLookup-4              	   27226	     43866 ns/op	  22796720 objects/sec	       0 B/op	       0 allocs/op
BenchmarkDB_FullIteration_All-4             	     723	   1675151 ns/op	  59696217 objects/sec	     464 B/op	      12 allocs/op
BenchmarkDB_FullIteration_Get-4             	     210	   5760992 ns/op	  17358152 objects/sec	       0 B/op	       0 allocs/op
BenchmarkDB_PropagationDelay-4              	  482103	      2356 ns/op	        20.00 50th_µs	        24.00 90th_µs	        64.00 99th_µs	    1584 B/op	      24 allocs/op
PASS
ok  	github.com/cilium/statedb	25.579s
PASS
ok  	github.com/cilium/statedb/index	0.003s
PASS
ok  	github.com/cilium/statedb/internal	0.003s
goos: linux
goarch: amd64
pkg: github.com/cilium/statedb/part
cpu: AMD EPYC 7763 64-Core Processor                
Benchmark_Insert_RootOnlyWatch-4    	    8805	    134715 ns/op	   7423076 objects/sec	  104160 B/op	    2041 allocs/op
Benchmark_Insert-4                  	    5906	    190279 ns/op	   5255448 objects/sec	  219061 B/op	    3065 allocs/op
Benchmark_Modify-4                  	    8112	    143900 ns/op	   6949286 objects/sec	  212578 B/op	    1205 allocs/op
Benchmark_GetInsert-4               	    6400	    181405 ns/op	   5512527 objects/sec	  212527 B/op	    1204 allocs/op
Benchmark_Replace-4                 	27083745	        44.29 ns/op	  22576758 objects/sec	       0 B/op	       0 allocs/op
Benchmark_Replace_RootOnlyWatch-4   	26487183	        44.33 ns/op	  22556126 objects/sec	       0 B/op	       0 allocs/op
Benchmark_txn_1-4                   	 2939096	       410.9 ns/op	   2433452 objects/sec	     448 B/op	       7 allocs/op
Benchmark_txn_10-4                  	 6303984	       164.9 ns/op	   6062596 objects/sec	     154 B/op	       2 allocs/op
Benchmark_txn_100-4                 	 7931842	       153.1 ns/op	   6532938 objects/sec	     224 B/op	       2 allocs/op
Benchmark_txn_1000-4                	 7021616	       168.3 ns/op	   5940683 objects/sec	     216 B/op	       2 allocs/op
Benchmark_txn_delete_1-4            	 3036086	       392.7 ns/op	   2546735 objects/sec	     856 B/op	       6 allocs/op
Benchmark_txn_delete_10-4           	 8650976	       137.5 ns/op	   7272343 objects/sec	     132 B/op	       1 allocs/op
Benchmark_txn_delete_100-4          	10674668	       110.5 ns/op	   9051375 objects/sec	      60 B/op	       1 allocs/op
Benchmark_txn_delete_1000-4         	11453516	       105.4 ns/op	   9492164 objects/sec	      26 B/op	       1 allocs/op
Benchmark_Get-4                     	   36776	     32730 ns/op	  30553245 objects/sec	       0 B/op	       0 allocs/op
Benchmark_Iterate-4                 	  160454	      7220 ns/op	 138503067 objects/sec	      80 B/op	       3 allocs/op
Benchmark_Hashmap_Insert-4          	   15709	     76754 ns/op	  13028655 objects/sec	   86557 B/op	      64 allocs/op
Benchmark_Hashmap_Get_Uint64-4      	  146472	      8211 ns/op	 121785674 objects/sec	       0 B/op	       0 allocs/op
Benchmark_Hashmap_Get_Bytes-4       	  160770	      7415 ns/op	 134862025 objects/sec	       0 B/op	       0 allocs/op
Benchmark_Uint64Map_Random-4        	    1339	    870012 ns/op	   1149411 items/sec	 2701253 B/op	    9038 allocs/op
Benchmark_Uint64Map_Sequential-4    	    1464	    808268 ns/op	   1237216 items/sec	 2492407 B/op	    9749 allocs/op
PASS
ok  	github.com/cilium/statedb/part	28.157s
PASS
ok  	github.com/cilium/statedb/reconciler	0.004s
?   	github.com/cilium/statedb/reconciler/benchmark	[no test files]
?   	github.com/cilium/statedb/reconciler/example	[no test files]
PASS
ok  	github.com/cilium/statedb/testutils	0.004s
go run ./reconciler/benchmark -quiet
1000000 objects reconciled in 2.97 seconds (batch size 1000)
Throughput 337058.06 objects per second
Allocated 6011229 objects, 424751kB bytes, 523640kB bytes still in use

@joamaki joamaki force-pushed the pr/joamaki/testutils branch 2 times, most recently from 6da0a1d to ac2acec Compare September 20, 2024 14:59
@joamaki joamaki changed the title [DRAFT] testutils: Add script-based test utilities testutils: Add script-based test utilities Sep 20, 2024
@joamaki joamaki marked this pull request as ready for review September 20, 2024 15:05
@joamaki joamaki requested a review from a team as a code owner September 20, 2024 15:05
@joamaki joamaki requested review from ovidiutirla and removed request for a team September 20, 2024 15:06
testutils/script.go Outdated Show resolved Hide resolved
testutils/script.go Outdated Show resolved Hide resolved
testutils/script.go Outdated Show resolved Hide resolved
testutils/script.go Show resolved Hide resolved
testutils/script.go Show resolved Hide resolved
testutils/script.go Show resolved Hide resolved
testutils/script.go Outdated Show resolved Hide resolved
testutils/script.go Outdated Show resolved Hide resolved
testutils/script.go Outdated Show resolved Hide resolved
testutils/script.go Outdated Show resolved Hide resolved
testutils/script.go Show resolved Hide resolved
testutils/script.go Outdated Show resolved Hide resolved
types.go Outdated
@@ -226,6 +230,8 @@ type TableMeta interface {
secondary() map[string]anyIndexer // Secondary indexers (if any)
sortableMutex() internal.SortableMutex // The sortable mutex for locking the table for writing
anyChanges(txn WriteTxn) (anyChangeIterator, error)
proto() any
unmarshalYAML(data string) (any, error)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add this here, part of the TableMeta as it's only usage will be part of this script.go, or extract to a different package/even the scriptutils.

Copy link
Contributor Author

@joamaki joamaki Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'll need to revisit these weird ones a bit and see how I can mostly hide them. They do need to be in the genTable though as that's the place where we know what Obj is, so I cannot put it anywhere else. I could of course put these behind something else than TableMeta interface and cast things around in any_table.go etc. Not sure what the benefit is.

The yaml thing was a bit annoying as I need to call yaml.Unmarshal with a concrete thing and if it goes via the any (e.g. by using proto() to get the zero object) it'll just end up producing map[string]any as a result. Will have to play around with it and see if I can get rid of it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I don't think there's a way around having unmarshalYAML here. We need to call yaml.Unmarshal on the concrete type as Unmarshal reflects on the type of the destination value and if we go via any we lose the type information at runtime. What I'll do though is split of the weird internal things into tableInternal interface so it's not so visible.

@joamaki joamaki force-pushed the pr/joamaki/testutils branch 4 times, most recently from d8dfe31 to 5fd4882 Compare September 26, 2024 14:57
Copy link

@ovidiutirla ovidiutirla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

testutils/script.go Outdated Show resolved Hide resolved
Add generic testscript commands for testing against
StateDB tables.

This allows implementing tests as scripts, which becomes useful when
tests perform multiple steps on tables and need to verify the output
each step.

Signed-off-by: Jussi Maki <[email protected]>
@joamaki joamaki merged commit da44c74 into main Sep 30, 2024
1 check passed
@joamaki joamaki deleted the pr/joamaki/testutils branch September 30, 2024 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants