4eeadd06a5
* refactor: move more commands to internal/cmd Part of https://github.com/ooni/probe/issues/1335. We would like all commands to be at the same level of engine rather than inside engine (now that we can do it). * fix: update .gitignore * refactor: also move jafar outside engine * We should be good now?
317 lines
8.1 KiB
Go
317 lines
8.1 KiB
Go
package engine_test
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"syscall"
|
|
"testing"
|
|
|
|
"github.com/apex/log"
|
|
"github.com/google/go-cmp/cmp"
|
|
engine "github.com/ooni/probe-cli/v3/internal/engine"
|
|
"github.com/ooni/probe-cli/v3/internal/engine/kvstore"
|
|
"github.com/ooni/probe-cli/v3/internal/engine/model"
|
|
)
|
|
|
|
func TestInputLoaderInputNoneWithStaticInputs(t *testing.T) {
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
StaticInputs: []string{"https://www.google.com/"},
|
|
InputPolicy: engine.InputNone,
|
|
})
|
|
ctx := context.Background()
|
|
out, err := il.Load(ctx)
|
|
if !errors.Is(err, engine.ErrNoInputExpected) {
|
|
t.Fatalf("not the error we expected: %+v", err)
|
|
}
|
|
if out != nil {
|
|
t.Fatal("not the output we expected")
|
|
}
|
|
}
|
|
|
|
func TestInputLoaderInputNoneWithFilesInputs(t *testing.T) {
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
SourceFiles: []string{
|
|
"testdata/inputloader1.txt",
|
|
"testdata/inputloader2.txt",
|
|
},
|
|
InputPolicy: engine.InputNone,
|
|
})
|
|
ctx := context.Background()
|
|
out, err := il.Load(ctx)
|
|
if !errors.Is(err, engine.ErrNoInputExpected) {
|
|
t.Fatalf("not the error we expected: %+v", err)
|
|
}
|
|
if out != nil {
|
|
t.Fatal("not the output we expected")
|
|
}
|
|
}
|
|
|
|
func TestInputLoaderInputNoneWithBothInputs(t *testing.T) {
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
StaticInputs: []string{"https://www.google.com/"},
|
|
SourceFiles: []string{
|
|
"testdata/inputloader1.txt",
|
|
"testdata/inputloader2.txt",
|
|
},
|
|
InputPolicy: engine.InputNone,
|
|
})
|
|
ctx := context.Background()
|
|
out, err := il.Load(ctx)
|
|
if !errors.Is(err, engine.ErrNoInputExpected) {
|
|
t.Fatalf("not the error we expected: %+v", err)
|
|
}
|
|
if out != nil {
|
|
t.Fatal("not the output we expected")
|
|
}
|
|
}
|
|
|
|
func TestInputLoaderInputNoneWithNoInput(t *testing.T) {
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
InputPolicy: engine.InputNone,
|
|
})
|
|
ctx := context.Background()
|
|
out, err := il.Load(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(out) != 1 || out[0].URL != "" {
|
|
t.Fatal("not the output we expected")
|
|
}
|
|
}
|
|
|
|
func TestInputLoaderInputOptionalWithNoInput(t *testing.T) {
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
InputPolicy: engine.InputOptional,
|
|
})
|
|
ctx := context.Background()
|
|
out, err := il.Load(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(out) != 1 || out[0].URL != "" {
|
|
t.Fatal("not the output we expected")
|
|
}
|
|
}
|
|
|
|
func TestInputLoaderInputOptionalWithInput(t *testing.T) {
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
StaticInputs: []string{"https://www.google.com/"},
|
|
SourceFiles: []string{
|
|
"testdata/inputloader1.txt",
|
|
"testdata/inputloader2.txt",
|
|
},
|
|
InputPolicy: engine.InputOptional,
|
|
})
|
|
ctx := context.Background()
|
|
out, err := il.Load(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(out) != 5 {
|
|
t.Fatal("not the output length we expected")
|
|
}
|
|
expect := []model.URLInfo{
|
|
{URL: "https://www.google.com/"},
|
|
{URL: "https://www.x.org/"},
|
|
{URL: "https://www.slashdot.org/"},
|
|
{URL: "https://abc.xyz/"},
|
|
{URL: "https://run.ooni.io/"},
|
|
}
|
|
if diff := cmp.Diff(out, expect); diff != "" {
|
|
t.Fatal(diff)
|
|
}
|
|
}
|
|
|
|
func TestInputLoaderInputOptionalNonexistentFile(t *testing.T) {
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
StaticInputs: []string{"https://www.google.com/"},
|
|
SourceFiles: []string{
|
|
"testdata/inputloader1.txt",
|
|
"/nonexistent",
|
|
"testdata/inputloader2.txt",
|
|
},
|
|
InputPolicy: engine.InputOptional,
|
|
})
|
|
ctx := context.Background()
|
|
out, err := il.Load(ctx)
|
|
if !errors.Is(err, syscall.ENOENT) {
|
|
t.Fatalf("not the error we expected: %+v", err)
|
|
}
|
|
if out != nil {
|
|
t.Fatal("not the output we expected")
|
|
}
|
|
}
|
|
|
|
func TestInputLoaderInputStrictlyRequiredWithInput(t *testing.T) {
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
StaticInputs: []string{"https://www.google.com/"},
|
|
SourceFiles: []string{
|
|
"testdata/inputloader1.txt",
|
|
"testdata/inputloader2.txt",
|
|
},
|
|
InputPolicy: engine.InputStrictlyRequired,
|
|
})
|
|
ctx := context.Background()
|
|
out, err := il.Load(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(out) != 5 {
|
|
t.Fatal("not the output length we expected")
|
|
}
|
|
expect := []model.URLInfo{
|
|
{URL: "https://www.google.com/"},
|
|
{URL: "https://www.x.org/"},
|
|
{URL: "https://www.slashdot.org/"},
|
|
{URL: "https://abc.xyz/"},
|
|
{URL: "https://run.ooni.io/"},
|
|
}
|
|
if diff := cmp.Diff(out, expect); diff != "" {
|
|
t.Fatal(diff)
|
|
}
|
|
}
|
|
|
|
func TestInputLoaderInputStrictlyRequiredWithoutInput(t *testing.T) {
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
InputPolicy: engine.InputStrictlyRequired,
|
|
})
|
|
ctx := context.Background()
|
|
out, err := il.Load(ctx)
|
|
if !errors.Is(err, engine.ErrInputRequired) {
|
|
t.Fatalf("not the error we expected: %+v", err)
|
|
}
|
|
if out != nil {
|
|
t.Fatal("not the output we expected")
|
|
}
|
|
}
|
|
|
|
func TestInputLoaderInputStrictlyRequiredWithEmptyFile(t *testing.T) {
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
InputPolicy: engine.InputStrictlyRequired,
|
|
SourceFiles: []string{
|
|
"testdata/inputloader1.txt",
|
|
"testdata/inputloader3.txt", // we want it before inputloader2.txt
|
|
"testdata/inputloader2.txt",
|
|
},
|
|
})
|
|
ctx := context.Background()
|
|
out, err := il.Load(ctx)
|
|
if !errors.Is(err, engine.ErrDetectedEmptyFile) {
|
|
t.Fatalf("not the error we expected: %+v", err)
|
|
}
|
|
if out != nil {
|
|
t.Fatal("not the output we expected")
|
|
}
|
|
}
|
|
|
|
func TestInputLoaderInputOrQueryTestListsWithInput(t *testing.T) {
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
StaticInputs: []string{"https://www.google.com/"},
|
|
SourceFiles: []string{
|
|
"testdata/inputloader1.txt",
|
|
"testdata/inputloader2.txt",
|
|
},
|
|
InputPolicy: engine.InputOrQueryTestLists,
|
|
})
|
|
ctx := context.Background()
|
|
out, err := il.Load(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(out) != 5 {
|
|
t.Fatal("not the output length we expected")
|
|
}
|
|
expect := []model.URLInfo{
|
|
{URL: "https://www.google.com/"},
|
|
{URL: "https://www.x.org/"},
|
|
{URL: "https://www.slashdot.org/"},
|
|
{URL: "https://abc.xyz/"},
|
|
{URL: "https://run.ooni.io/"},
|
|
}
|
|
if diff := cmp.Diff(out, expect); diff != "" {
|
|
t.Fatal(diff)
|
|
}
|
|
}
|
|
|
|
func TestInputLoaderInputOrQueryTestListsWithNoInputAndCancelledContext(t *testing.T) {
|
|
sess, err := engine.NewSession(engine.SessionConfig{
|
|
AssetsDir: "testdata",
|
|
KVStore: kvstore.NewMemoryKeyValueStore(),
|
|
Logger: log.Log,
|
|
SoftwareName: "miniooni",
|
|
SoftwareVersion: "0.1.0-dev",
|
|
TempDir: "testdata",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer sess.Close()
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
InputPolicy: engine.InputOrQueryTestLists,
|
|
Session: sess,
|
|
})
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel() // fail immediately
|
|
out, err := il.Load(ctx)
|
|
if !errors.Is(err, context.Canceled) {
|
|
t.Fatalf("not the error we expected: %+v", err)
|
|
}
|
|
if out != nil {
|
|
t.Fatal("not the output we expected")
|
|
}
|
|
}
|
|
|
|
func TestInputLoaderInputOrQueryTestListsWithNoInput(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("skip test in short mode")
|
|
}
|
|
sess, err := engine.NewSession(engine.SessionConfig{
|
|
AvailableProbeServices: []model.Service{{
|
|
Address: "https://ams-pg-test.ooni.org/",
|
|
Type: "https",
|
|
}},
|
|
AssetsDir: "testdata",
|
|
KVStore: kvstore.NewMemoryKeyValueStore(),
|
|
Logger: log.Log,
|
|
SoftwareName: "miniooni",
|
|
SoftwareVersion: "0.1.0-dev",
|
|
TempDir: "testdata",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer sess.Close()
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
InputPolicy: engine.InputOrQueryTestLists,
|
|
Session: sess,
|
|
URLLimit: 30,
|
|
})
|
|
ctx := context.Background()
|
|
out, err := il.Load(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(out) < 10 {
|
|
t.Fatal("not the output length we expected")
|
|
}
|
|
}
|
|
|
|
func TestInputLoaderInputOrQueryTestListsWithEmptyFile(t *testing.T) {
|
|
il := engine.NewInputLoader(engine.InputLoaderConfig{
|
|
InputPolicy: engine.InputOrQueryTestLists,
|
|
SourceFiles: []string{
|
|
"testdata/inputloader1.txt",
|
|
"testdata/inputloader3.txt", // we want it before inputloader2.txt
|
|
"testdata/inputloader2.txt",
|
|
},
|
|
})
|
|
ctx := context.Background()
|
|
out, err := il.Load(ctx)
|
|
if !errors.Is(err, engine.ErrDetectedEmptyFile) {
|
|
t.Fatalf("not the error we expected: %+v", err)
|
|
}
|
|
if out != nil {
|
|
t.Fatal("not the output we expected")
|
|
}
|
|
}
|