libct/spec: replace isValidName regex with a function

Also, add a simple test and a benchmark (just out of sheer curiosity).

Benchmark results:

name           old time/op  new time/op  delta
IsValidName-4   540ns ± 3%    45ns ± 1%  -91.76%  (p=0.008 n=5+5)

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Kir Kolyshkin
2021-11-12 17:03:28 -08:00
parent 6907becaf9
commit 029b73c1b0
2 changed files with 48 additions and 3 deletions

View File

@@ -7,7 +7,6 @@ import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"sync"
"time"
@@ -411,8 +410,21 @@ func createLibcontainerMount(cwd string, m specs.Mount) (*configs.Mount, error)
return mnt, nil
}
// systemd property name check: latin letters only, at least 3 of them
var isValidName = regexp.MustCompile(`^[a-zA-Z]{3,}$`).MatchString
// isValidName checks if systemd property name is valid. It should consists
// of latin letters only, and have least 3 of them.
func isValidName(s string) bool {
if len(s) < 3 {
return false
}
// Check ASCII characters rather than Unicode runes.
for _, ch := range s {
if (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') {
continue
}
return false
}
return true
}
// Some systemd properties are documented as having "Sec" suffix
// (e.g. TimeoutStopSec) but are expected to have "USec" suffix

View File

@@ -762,6 +762,39 @@ func TestInitSystemdProps(t *testing.T) {
}
}
func TestIsValidName(t *testing.T) {
testCases := []struct {
in string
valid bool
}{
{"", false}, // too short
{"xx", false}, // too short
{"xxx", true},
{"someValidName", true},
{"A name", false}, // space
{"3335", false}, // numbers
{"Name1", false}, // numbers
{"Кир", false}, // non-ascii
{"მადლობა", false}, // non-ascii
{"合い言葉", false}, // non-ascii
}
for _, tc := range testCases {
valid := isValidName(tc.in)
if valid != tc.valid {
t.Errorf("case %q: expected %v, got %v", tc.in, tc.valid, valid)
}
}
}
func BenchmarkIsValidName(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, s := range []string{"", "xx", "xxx", "someValidName", "A name", "Кир", "მადლობა", "合い言葉"} {
_ = isValidName(s)
}
}
}
func TestNullProcess(t *testing.T) {
spec := Example()
spec.Process = nil