123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- // Copyright (c) 2020 Shivaram Lingamneni <slingamn@cs.stanford.edu>
- // released under the MIT license
-
- package utils
-
- import (
- "regexp"
- "testing"
- )
-
- func globMustCompile(glob string) *regexp.Regexp {
- re, err := CompileGlob(glob, false)
- if err != nil {
- panic(err)
- }
- return re
- }
-
- func assertMatches(glob, str string, match bool, t *testing.T) {
- re := globMustCompile(glob)
- if re.MatchString(str) != match {
- t.Errorf("should %s match %s? %t, but got %t instead", glob, str, match, !match)
- }
- }
-
- func TestGlob(t *testing.T) {
- assertMatches("https://testnet.oragono.io", "https://testnet.oragono.io", true, t)
- assertMatches("https://*.oragono.io", "https://testnet.oragono.io", true, t)
- assertMatches("*://*.oragono.io", "https://testnet.oragono.io", true, t)
- assertMatches("*://*.oragono.io", "https://oragono.io", false, t)
- assertMatches("*://*.oragono.io", "https://githubusercontent.com", false, t)
- assertMatches("*://*.oragono.io", "https://testnet.oragono.io.example.com", false, t)
-
- assertMatches("", "", true, t)
- assertMatches("", "x", false, t)
- assertMatches("*", "", true, t)
- assertMatches("*", "x", true, t)
-
- assertMatches("c?b", "cab", true, t)
- assertMatches("c?b", "cub", true, t)
- assertMatches("c?b", "cb", false, t)
- assertMatches("c?b", "cube", false, t)
- assertMatches("?*", "cube", true, t)
- assertMatches("?*", "", false, t)
-
- assertMatches("S*e", "Skåne", true, t)
- assertMatches("Sk?ne", "Skåne", true, t)
- }
-
- func BenchmarkGlob(b *testing.B) {
- g := globMustCompile("https://*google.com")
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- g.MatchString("https://www.google.com")
- }
- }
-
- func BenchmarkGlobCompilation(b *testing.B) {
- for i := 0; i < b.N; i++ {
- CompileGlob("https://*google.com", false)
- }
- }
-
- // these are actual bans from my production network :-/
- var bans = []string{
- "*!*@tor-network.onion",
- "`!*@*",
- "qanon!*@*",
- "*!bibi@tor-network.onion",
- "shivarm!*@*",
- "8====d!*@*",
- "shiviram!*@*",
- "poop*!*@*",
- "shivoram!*@*",
- "shivvy!*@*",
- "shavirim!*@*",
- "shivarm_!*@*",
- "_!*@*",
- }
-
- func TestMasks(t *testing.T) {
- matcher, err := CompileMasks(bans)
- if err != nil {
- panic(err)
- }
-
- if !matcher.MatchString("evan!user@tor-network.onion") {
- t.Errorf("match expected")
- }
- if !matcher.MatchString("`!evan@b9un4fv3he44q.example.com") {
- t.Errorf("match expected")
- }
- if matcher.MatchString("horse!horse@t5dwi8vacg47y.example.com") {
- t.Errorf("match not expected")
- }
- if matcher.MatchString("horse_!horse@t5dwi8vacg47y.example.com") {
- t.Errorf("match not expected")
- }
- if matcher.MatchString("shivaram!shivaram@yrqgsrjy2p7my.example.com") {
- t.Errorf("match not expected")
- }
- }
-
- func BenchmarkMasksCompile(b *testing.B) {
- for i := 0; i < b.N; i++ {
- CompileMasks(bans)
- }
- }
-
- func BenchmarkMasksMatch(b *testing.B) {
- matcher, _ := CompileMasks(bans)
-
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- matcher.MatchString("evan!user@tor-network.onion")
- matcher.MatchString("horse_!horse@t5dwi8vacg47y.example.com")
- matcher.MatchString("shivaram!shivaram@yrqgsrjy2p7my.example.com")
- }
- }
-
- // compare performance to compilation of the | clauses as separate regexes
- // first for compilation, then for matching
-
- func compileAll(masks []string) (result []*regexp.Regexp, err error) {
- a := make([]*regexp.Regexp, 0, len(masks))
- for _, mask := range masks {
- m, err := CompileGlob(mask, false)
- if err != nil {
- return nil, err
- }
- a = append(a, m)
- }
- return a, nil
- }
-
- func matchesAny(masks []*regexp.Regexp, str string) bool {
- for _, r := range masks {
- if r.MatchString(str) {
- return true
- }
- }
- return false
- }
-
- func BenchmarkLinearCompile(b *testing.B) {
- for i := 0; i < b.N; i++ {
- compileAll(bans)
- }
- }
-
- func BenchmarkLinearMatch(b *testing.B) {
- a, err := compileAll(bans)
- if err != nil {
- panic(err)
- }
- if matchesAny(a, "horse_!horse@t5dwi8vacg47y.example.com") {
- panic("incorrect match")
- }
- if !matchesAny(a, "evan!user@tor-network.onion") {
- panic("incorrect match")
- }
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- matchesAny(a, "horse_!horse@t5dwi8vacg47y.example.com")
- matchesAny(a, "evan!user@tor-network.onion")
- matchesAny(a, "shivaram!shivaram@yrqgsrjy2p7my.example.com")
- }
- }
|