2017-06-28 11:01:36 +00:00
|
|
|
package enry
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
|
|
|
"os"
|
2017-07-18 11:29:46 +00:00
|
|
|
"os/exec"
|
2017-06-28 11:01:36 +00:00
|
|
|
"path/filepath"
|
|
|
|
"testing"
|
|
|
|
|
2017-07-18 11:29:46 +00:00
|
|
|
"gopkg.in/src-d/enry.v1/data"
|
|
|
|
)
|
2017-06-28 11:01:36 +00:00
|
|
|
|
|
|
|
type sample struct {
|
|
|
|
filename string
|
|
|
|
content []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
slow bool
|
|
|
|
overcomeLanguage string
|
|
|
|
overcomeLanguages []string
|
|
|
|
samples []*sample
|
2017-07-18 11:29:46 +00:00
|
|
|
samplesDir string
|
2017-10-26 13:37:18 +00:00
|
|
|
cloned bool
|
2017-06-28 11:01:36 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestMain(m *testing.M) {
|
2017-07-18 11:29:46 +00:00
|
|
|
var exitCode int
|
|
|
|
defer os.Exit(exitCode)
|
|
|
|
|
2017-06-28 11:01:36 +00:00
|
|
|
flag.BoolVar(&slow, "slow", false, "run benchmarks per sample for strategies too")
|
|
|
|
flag.Parse()
|
2017-07-18 11:29:46 +00:00
|
|
|
|
|
|
|
if err := cloneLinguist(linguistURL); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2017-10-26 13:37:18 +00:00
|
|
|
if cloned {
|
|
|
|
defer os.RemoveAll(filepath.Dir(samplesDir))
|
|
|
|
}
|
2017-07-18 11:29:46 +00:00
|
|
|
|
2017-06-28 11:01:36 +00:00
|
|
|
var err error
|
|
|
|
samples, err = getSamples(samplesDir)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2017-07-18 11:29:46 +00:00
|
|
|
exitCode = m.Run()
|
|
|
|
}
|
|
|
|
|
|
|
|
func cloneLinguist(linguistURL string) error {
|
2017-10-26 13:37:18 +00:00
|
|
|
repoLinguist := os.Getenv(linguistClonedEnvVar)
|
|
|
|
cloned = repoLinguist == ""
|
|
|
|
if cloned {
|
|
|
|
var err error
|
|
|
|
repoLinguist, err = ioutil.TempDir("", "linguist-")
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-07-18 11:29:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
samplesDir = filepath.Join(repoLinguist, "samples")
|
|
|
|
|
2017-10-26 13:37:18 +00:00
|
|
|
if cloned {
|
|
|
|
cmd := exec.Command("git", "clone", linguistURL, repoLinguist)
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-07-18 11:29:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cwd, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = os.Chdir(repoLinguist); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-10-26 13:37:18 +00:00
|
|
|
cmd := exec.Command("git", "checkout", data.LinguistCommit)
|
2017-07-18 11:29:46 +00:00
|
|
|
if err := cmd.Run(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = os.Chdir(cwd); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2017-06-28 11:01:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func getSamples(dir string) ([]*sample, error) {
|
|
|
|
samples := make([]*sample, 0, 2000)
|
|
|
|
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if info.IsDir() {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
content, err := ioutil.ReadFile(path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
s := &sample{
|
|
|
|
filename: path,
|
|
|
|
content: content,
|
|
|
|
}
|
|
|
|
|
|
|
|
samples = append(samples, s)
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
|
|
|
return samples, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkGetLanguageTotal(b *testing.B) {
|
|
|
|
if slow {
|
|
|
|
b.SkipNow()
|
|
|
|
}
|
|
|
|
|
|
|
|
var o string
|
|
|
|
b.Run("GetLanguage()_TOTAL", func(b *testing.B) {
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
for _, sample := range samples {
|
|
|
|
o = GetLanguage(sample.filename, sample.content)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
overcomeLanguage = o
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkClassifyTotal(b *testing.B) {
|
|
|
|
if slow {
|
|
|
|
b.SkipNow()
|
|
|
|
}
|
|
|
|
|
|
|
|
var o []string
|
|
|
|
b.Run("Classify()_TOTAL", func(b *testing.B) {
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
for _, sample := range samples {
|
|
|
|
o = DefaultClassifier.Classify(sample.content, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
overcomeLanguages = o
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkStrategiesTotal(b *testing.B) {
|
|
|
|
if slow {
|
|
|
|
b.SkipNow()
|
|
|
|
}
|
|
|
|
|
|
|
|
benchmarks := []struct {
|
|
|
|
name string
|
|
|
|
strategy Strategy
|
|
|
|
candidates []string
|
|
|
|
}{
|
|
|
|
{name: "GetLanguagesByModeline()_TOTAL", strategy: GetLanguagesByModeline},
|
|
|
|
{name: "GetLanguagesByFilename()_TOTAL", strategy: GetLanguagesByFilename},
|
|
|
|
{name: "GetLanguagesByShebang()_TOTAL", strategy: GetLanguagesByShebang},
|
|
|
|
{name: "GetLanguagesByExtension()_TOTAL", strategy: GetLanguagesByExtension},
|
|
|
|
{name: "GetLanguagesByContent()_TOTAL", strategy: GetLanguagesByContent},
|
|
|
|
}
|
|
|
|
|
|
|
|
var o []string
|
|
|
|
for _, benchmark := range benchmarks {
|
|
|
|
b.Run(benchmark.name, func(b *testing.B) {
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
for _, sample := range samples {
|
|
|
|
o = benchmark.strategy(sample.filename, sample.content, benchmark.candidates)
|
|
|
|
}
|
|
|
|
|
|
|
|
overcomeLanguages = o
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkGetLanguagePerSample(b *testing.B) {
|
|
|
|
if !slow {
|
|
|
|
b.SkipNow()
|
|
|
|
}
|
|
|
|
|
|
|
|
var o string
|
|
|
|
for _, sample := range samples {
|
|
|
|
b.Run("GetLanguage()_SAMPLE_"+sample.filename, func(b *testing.B) {
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
o = GetLanguage(sample.filename, sample.content)
|
|
|
|
}
|
|
|
|
|
|
|
|
overcomeLanguage = o
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkClassifyPerSample(b *testing.B) {
|
|
|
|
if !slow {
|
|
|
|
b.SkipNow()
|
|
|
|
}
|
|
|
|
|
|
|
|
var o []string
|
|
|
|
for _, sample := range samples {
|
|
|
|
b.Run("Classify()_SAMPLE_"+sample.filename, func(b *testing.B) {
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
o = DefaultClassifier.Classify(sample.content, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
overcomeLanguages = o
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkStrategiesPerSample(b *testing.B) {
|
|
|
|
if !slow {
|
|
|
|
b.SkipNow()
|
|
|
|
}
|
|
|
|
|
|
|
|
benchmarks := []struct {
|
|
|
|
name string
|
|
|
|
strategy Strategy
|
|
|
|
candidates []string
|
|
|
|
}{
|
|
|
|
{name: "GetLanguagesByModeline()_SAMPLE_", strategy: GetLanguagesByModeline},
|
|
|
|
{name: "GetLanguagesByFilename()_SAMPLE_", strategy: GetLanguagesByFilename},
|
|
|
|
{name: "GetLanguagesByShebang()_SAMPLE_", strategy: GetLanguagesByShebang},
|
|
|
|
{name: "GetLanguagesByExtension()_SAMPLE_", strategy: GetLanguagesByExtension},
|
|
|
|
{name: "GetLanguagesByContent()_SAMPLE_", strategy: GetLanguagesByContent},
|
|
|
|
}
|
|
|
|
|
|
|
|
var o []string
|
|
|
|
for _, benchmark := range benchmarks {
|
|
|
|
for _, sample := range samples {
|
|
|
|
b.Run(benchmark.name+sample.filename, func(b *testing.B) {
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
o = benchmark.strategy(sample.filename, sample.content, benchmark.candidates)
|
|
|
|
}
|
|
|
|
|
|
|
|
overcomeLanguages = o
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|