1
0
mirror of https://github.com/gilbertchen/duplicacy synced 2025-12-15 07:43:21 +00:00
Files
duplicacy/src/duplicacy_utils_test.go

150 lines
4.0 KiB
Go

// Copyright (c) Acrosync LLC. All rights reserved.
// Free for personal use and commercial trial
// Commercial use requires per-user licenses available from https://duplicacy.com
package duplicacy
import (
"bytes"
"io"
"io/ioutil"
"time"
crypto_rand "crypto/rand"
"testing"
)
func TestMatchPattern(t *testing.T) {
// Test cases were copied from Matching Wildcards: An Empirical Way to Tame an Algorithm
// By Kirk J. Krauss, October 07, 2014
DATA := []struct {
text string
pattern string
matched bool
}{
// Cases with repeating character sequences.
{"abcccd", "*ccd", true},
{"mississipissippi", "*issip*ss*", true},
{"xxxx*zzzzzzzzy*f", "xxxx*zzy*fffff", false},
{"xxxx*zzzzzzzzy*f", "xxx*zzy*f", true},
{"xxxxzzzzzzzzyf", "xxxx*zzy*fffff", false},
{"xxxxzzzzzzzzyf", "xxxx*zzy*f", true},
{"xyxyxyzyxyz", "xy*z*xyz", true},
{"mississippi", "*sip*", true},
{"xyxyxyxyz", "xy*xyz", true},
{"mississippi", "mi*sip*", true},
{"ababac", "*abac*", true},
{"ababac", "*abac*", true},
{"aaazz", "a*zz*", true},
{"a12b12", "*12*23", false},
{"a12b12", "a12b", false},
{"a12b12", "*12*12*", true},
// More double wildcard scenarios.
{"XYXYXYZYXYz", "XY*Z*XYz", true},
{"missisSIPpi", "*SIP*", true},
{"mississipPI", "*issip*PI", true},
{"xyxyxyxyz", "xy*xyz", true},
{"miSsissippi", "mi*sip*", true},
{"miSsissippi", "mi*Sip*", false},
{"abAbac", "*Abac*", true},
{"abAbac", "*Abac*", true},
{"aAazz", "a*zz*", true},
{"A12b12", "*12*23", false},
{"a12B12", "*12*12*", true},
{"oWn", "*oWn*", true},
// Completely tame (no wildcards) cases.
{"bLah", "bLah", true},
{"bLah", "bLaH", false},
// Simple mixed wildcard tests suggested by IBMer Marlin Deckert.
{"a", "*?", true},
{"ab", "*?", true},
{"abc", "*?", true},
// More mixed wildcard tests including coverage for false positives.
{"a", "??", false},
{"ab", "?*?", true},
{"ab", "*?*?*", true},
{"abc", "?*?*?", true},
{"abc", "?*?*&?", false},
{"abcd", "?b*??", true},
{"abcd", "?a*??", false},
{"abcd", "?*?c?", true},
{"abcd", "?*?d?", false},
{"abcde", "?*b*?*d*?", true},
// Single-character-match cases.
{"bLah", "bL?h", true},
{"bLaaa", "bLa?", false},
{"bLah", "bLa?", true},
{"bLaH", "?Lah", false},
{"bLaH", "?LaH", true},
}
for _, data := range DATA {
if matchPattern(data.text, data.pattern) != data.matched {
t.Errorf("text: %s, pattern %s, expected: %t", data.text, data.pattern, data.matched)
}
}
for _, pattern := range []string{ "+", "-", "i:", "e:", "+a", "-a", "i:a", "e:a"} {
if IsUnspecifiedFilter(pattern) {
t.Errorf("pattern %s has a specified filter", pattern)
}
}
for _, pattern := range []string{ "i", "e", "ia", "ib", "a", "b"} {
if !IsUnspecifiedFilter(pattern) {
t.Errorf("pattern %s does not have a specified filter", pattern)
}
}
}
func TestRateLimit(t *testing.T) {
content := make([]byte, 100*1024)
_, err := crypto_rand.Read(content)
if err != nil {
t.Errorf("Error generating random content: %v", err)
return
}
expectedRate := 10
rateLimiter := CreateRateLimitedReader(content, expectedRate)
startTime := time.Now()
n, err := io.Copy(ioutil.Discard, rateLimiter)
if err != nil {
t.Errorf("Error reading from the rate limited reader: %v", err)
return
}
if int(n) != len(content) {
t.Errorf("Wrote %d bytes instead of %d", n, len(content))
return
}
elapsed := time.Since(startTime)
actualRate := float64(len(content)) / elapsed.Seconds() / 1024
t.Logf("Elapsed time: %s, actual rate: %.3f kB/s, expected rate: %d kB/s", elapsed, actualRate, expectedRate)
startTime = time.Now()
n, err = RateLimitedCopy(ioutil.Discard, bytes.NewBuffer(content), expectedRate)
if err != nil {
t.Errorf("Error writing with rate limit: %v", err)
return
}
if int(n) != len(content) {
t.Errorf("Copied %d bytes instead of %d", n, len(content))
return
}
elapsed = time.Since(startTime)
actualRate = float64(len(content)) / elapsed.Seconds() / 1024
t.Logf("Elapsed time: %s, actual rate: %.3f kB/s, expected rate: %d kB/s", elapsed, actualRate, expectedRate)
}