func getDir(t *testing.T, dirPath string, cliArgs ...string) *fs.Dir {
	t.Helper()
	cmd := mybase.NewCommand("lintertest", "", "", nil)
	util.AddGlobalOptions(cmd)
	workspace.AddCommandOptions(cmd)
	AddCommandOptions(cmd)
	cmd.AddArg("environment", "production", false)
	commandLine := "lintertest"
	if len(cliArgs) > 0 {
		commandLine = fmt.Sprintf("lintertest %s", strings.Join(cliArgs, " "))
	}
	cfg := mybase.ParseFakeCLI(t, cmd, commandLine)
	dir, err := fs.ParseDir(dirPath, cfg)
	if err != nil {
		t.Fatalf("Unexpected error parsing dir %s: %s", dirPath, err)
	}
	return dir
}
getDir parses and returns an *fs.Dir
package linter
import (
	"fmt"
	"os"
	"regexp"
	"strings"
	"testing"
	"github.com/skeema/mybase"
	"github.com/skeema/skeema/internal/fs"
	"github.com/skeema/skeema/internal/util"
	"github.com/skeema/skeema/internal/workspace"
	"github.com/skeema/tengo"
)
func TestMain(m *testing.M) {
	tengo.UseFilteredDriverLogger()
	os.Exit(m.Run())
}
func TestIntegration(t *testing.T) {
	images := tengo.SplitEnv("SKEEMA_TEST_IMAGES")
	if len(images) == 0 {
		fmt.Println("SKEEMA_TEST_IMAGES env var is not set, so integration tests will be skipped!")
		fmt.Println("To run integration tests, you may set SKEEMA_TEST_IMAGES to a comma-separated")
		fmt.Println("list of Docker images. Example:\n# SKEEMA_TEST_IMAGES=\"mysql:5.6,mysql:5.7\" go test")
	}
	manager, err := tengo.NewDockerClient(tengo.DockerClientOptions{})
	if err != nil {
		t.Errorf("Unable to create sandbox manager: %s", err)
	}
	suite := &IntegrationSuite{manager: manager}
	tengo.RunSuite(suite, t, images)
}
type IntegrationSuite struct {
	manager       *tengo.DockerClient
	d             *tengo.DockerizedInstance
	schema        *tengo.Schema
	logicalSchema *fs.LogicalSchema
}
func (s IntegrationSuite) TestCheckSchema(t *testing.T) {
	dir := getDir(t, "testdata/validcfg")
	opts, err := OptionsForDir(dir)
	if err != nil {
		t.Fatalf("Unexpected error from OptionsForDir: %v", err)
	}
	forceRulesWarning(opts)
	opts.Flavor = s.d.Flavor()
	expectFailures := 3
	if opts.Flavor.VendorMinVersion(tengo.VendorMariaDB, 10, 6) {
		expectFailures += 2  
	}
	logicalSchema := dir.LogicalSchemas[0]
	wsOpts, err := workspace.OptionsForDir(dir, s.d.Instance)
	if err != nil {
		t.Fatalf("Unexpected error from workspace.OptionsForDir: %v", err)
	}
	wsSchema, err := workspace.ExecLogicalSchema(logicalSchema, wsOpts)
	if err != nil {
		t.Fatalf("Unexpected error from workspace.ExecLogicalSchema: %v", err)
	} else if len(wsSchema.Failures) != expectFailures {
		for _, err := range wsSchema.Failures {
			t.Errorf(err.Error())
		}
		t.Fatalf("Expected %d creation failures from %s/*.sql, instead found %d", expectFailures, dir, len(wsSchema.Failures))
	}
	result := CheckSchema(wsSchema, opts)
	expected := expectedAnnotations(logicalSchema, s.d.Flavor())
	compareAnnotations(t, expected, result)
}
func (s IntegrationSuite) TestCheckSchemaHidden(t *testing.T) {
	dir := getDir(t, "testdata/hidden")
	opts, err := OptionsForDir(dir)
	if err != nil {
		t.Fatalf("Unexpected error from OptionsForDir: %v", err)
	}
	forceOnlyRulesWarning(opts, "nullable", "ids")
	opts.Flavor = s.d.Flavor()
	logicalSchema := dir.LogicalSchemas[0]
	wsOpts, err := workspace.OptionsForDir(dir, s.d.Instance)
	if err != nil {
		t.Fatalf("Unexpected error from workspace.OptionsForDir: %v", err)
	}
	wsSchema, err := workspace.ExecLogicalSchema(logicalSchema, wsOpts)
	if err != nil {
		t.Fatalf("Unexpected error from workspace.ExecLogicalSchema: %v", err)
	} else if len(wsSchema.Failures) > 0 {
		t.Fatalf("Unexpectedly found %d failing CREATE statements in %s/*.sql", len(wsSchema.Failures), dir)
	}
	result := CheckSchema(wsSchema, opts)
	expected := expectedAnnotations(logicalSchema, s.d.Flavor())
	compareAnnotations(t, expected, result)
}
func (s IntegrationSuite) TestCheckSchemaCompression(t *testing.T) {
	dir := getDir(t, "testdata/validcfg")
	opts, err := OptionsForDir(dir)
	if err != nil {
		t.Fatalf("Unexpected error from OptionsForDir: %v", err)
	}
	logicalSchema := dir.LogicalSchemas[0]
	wsOpts, err := workspace.OptionsForDir(dir, s.d.Instance)
	if err != nil {
		t.Fatalf("Unexpected error from workspace.OptionsForDir: %v", err)
	}
	wsSchema, err := workspace.ExecLogicalSchema(logicalSchema, wsOpts)
	if err != nil {
		t.Fatalf("Unexpected error from workspace.ExecLogicalSchema: %v", err)
	}
	forceOnlyRulesWarning(opts, "compression")
	var innoTableCount int
	for _, tbl := range wsSchema.Tables {
		if tbl.Engine == "InnoDB" {
			innoTableCount++
		}
	}
	if !s.d.Flavor().VendorMinVersion(tengo.VendorMariaDB, 10, 6) {
		cases := []struct {
			allowList            []string
			flavor               tengo.Flavor
			expectedWarningCount int
		}{
			{[]string{"8kb"}, s.d.Flavor(), innoTableCount - 1},
			{[]string{"page", "8kb"}, tengo.FlavorMySQL57, innoTableCount - 1},
			{[]string{"page"}, tengo.FlavorMariaDB103, innoTableCount},
			{[]string{"none"}, s.d.Flavor(), 2},
			{[]string{"none", "4kb"}, s.d.Flavor(), 2},
			{[]string{"none", "4kb", "page"}, s.d.Flavor(), 2},
			{[]string{"none", "invalid-value"}, s.d.Flavor(), 2},
			{[]string{"invalid-value"}, s.d.Flavor(), innoTableCount},
		}
		for n, c := range cases {
			opts.RuleConfig["compression"] = c.allowList
			opts.Flavor = c.flavor
			result := CheckSchema(wsSchema, opts)
			if result.WarningCount != c.expectedWarningCount {
				t.Errorf("cases[%d] expected warning count %d, instead found %d", n, c.expectedWarningCount, result.WarningCount)
			}
		}
	}
	var tableExpectedClause map[string]string
	if s.d.Flavor().MySQLishMinVersion(5, 7) {
		dir = getDir(t, "testdata/pagecomprmysql")
		tableExpectedClause = map[string]string{
			"page_comp_zlib": "COMPRESSION='zlib'",
			"page_comp_lz4":  "COMPRESSION='lz4'",
			"page_comp_none": "",
		}
	} else if s.d.Flavor().VendorMinVersion(tengo.VendorMariaDB, 10, 2) {
		dir = getDir(t, "testdata/pagecomprmaria")
		tableExpectedClause = map[string]string{
			"page_comp_1":   "`PAGE_COMPRESSED`=1",
			"page_comp_on":  "`PAGE_COMPRESSED`='on'",
			"page_comp_0":   "",
			"page_comp_off": "",
		}
	}
	if tableExpectedClause != nil {
		logicalSchema := dir.LogicalSchemas[0]
		wsOpts, err := workspace.OptionsForDir(dir, s.d.Instance)
		if err != nil {
			t.Fatalf("Unexpected error from workspace.OptionsForDir: %v", err)
		}
		wsSchema, err := workspace.ExecLogicalSchema(logicalSchema, wsOpts)
		if err != nil {
			t.Fatalf("Unexpected error from workspace.ExecLogicalSchema: %v", err)
		}
		if len(wsSchema.Failures) > 0 {
			t.Fatalf("%d of the CREATEs in %s unexpectedly failed: %+v", len(wsSchema.Failures), dir, wsSchema.Failures)
		}
		for _, tbl := range wsSchema.Tables {
			expectedClause, ok := tableExpectedClause[tbl.Name]
			if !ok {
				t.Fatalf("Unexpectedly found table %s in dir %s, not present in tableExpectedClause mapping for flavor %s", tbl.Name, dir, s.d.Flavor())
			}
			var expectedMode string
			if expectedClause == "" {
				expectedMode = "none"
			} else {
				expectedMode = "page"
			}
			actualMode, actualClause := tableCompressionMode(tbl)
			if actualMode != expectedMode || actualClause != expectedClause {
				t.Errorf("Unexpected return value from tableCompressionMode(%s): got %q,%q; expected %q,%q", tbl.Name, actualMode, actualClause, expectedMode, expectedClause)
			}
		}
	}
}
func (s IntegrationSuite) TestCheckSchemaUTF8MB3(t *testing.T) {
	dir := getDir(t, "testdata/utf8mb3")
	opts, err := OptionsForDir(dir)
	if err != nil {
		t.Fatalf("Unexpected error from OptionsForDir: %v", err)
	}
	logicalSchema := dir.LogicalSchemas[0]
	wsOpts, err := workspace.OptionsForDir(dir, s.d.Instance)
	if err != nil {
		t.Fatalf("Unexpected error from workspace.OptionsForDir: %v", err)
	}
	wsSchema, err := workspace.ExecLogicalSchema(logicalSchema, wsOpts)
	if err != nil {
		t.Fatalf("Unexpected error from workspace.ExecLogicalSchema: %v", err)
	} else if len(wsSchema.Failures) != 0 {
		t.Fatalf("Unexpectedly found %d workspace failures", len(wsSchema.Failures))
	}
	forceOnlyRulesWarning(opts, "charset")
	opts.Flavor = s.d.Flavor()
	result := CheckSchema(wsSchema, opts)
	expected := expectedAnnotations(logicalSchema, s.d.Flavor())
	compareAnnotations(t, expected, result)
}
func (s *IntegrationSuite) Setup(backend string) (err error) {
	s.d, err = s.manager.GetOrCreateInstance(tengo.DockerizedInstanceOptions{
		Name:              fmt.Sprintf("skeema-test-%s", strings.Replace(backend, ":", "-", -1)),
		Image:             backend,
		RootPassword:      "fakepw",
		DefaultConnParams: "foreign_key_checks=0&sql_mode=%27NO_ENGINE_SUBSTITUTION%27",  
	})
	return err
}
func (s *IntegrationSuite) Teardown(backend string) error {
	return s.d.Stop()
}
func (s *IntegrationSuite) BeforeTest(backend string) error {
	return s.d.NukeData()
}