// runTests runs Logstash with a set of configuration files against a
// slice of test cases and compares the actual events against the
// expected set. Returns an error if at least one test case fails or
// if there's a problem running the tests.
func runTests(logstashPath string, tests []testcase.TestCase, configPaths []string, diffCommand []string) error {
	ok := true
	for _, t := range tests {
		p, err := logstash.NewProcess(logstashPath, t.Codec, t.InputFields, configPaths...)
		if err != nil {
			return err
		}
		defer p.Release()
		if err = p.Start(); err != nil {
			return err
		}

		for _, line := range t.InputLines {
			p.Input.Write([]byte(line + "\n"))
		}
		p.Input.Close()

		result, err := p.Wait()
		if err != nil {
			return err
		}
		if err = t.Compare(result.Events, false, diffCommand); err != nil {
			userError("Testcase failed, continuing with the rest: %s", err.Error())
			ok = false
		}
	}
	if !ok {
		return errors.New("One or more testcases failed.")
	}
	return nil
}
// runTests runs Logstash with a set of configuration files against a
// slice of test cases and compares the actual events against the
// expected set. Returns an error if at least one test case fails or
// if there's a problem running the tests.
func runTests(logstashPath string, tests []testcase.TestCase, configPaths []string, diffCommand []string, keptEnvVars []string) error {
	ok := true
	for _, t := range tests {
		p, err := logstash.NewProcess(logstashPath, t.Codec, t.InputFields, keptEnvVars, configPaths...)
		if err != nil {
			return err
		}
		defer p.Release()
		if err = p.Start(); err != nil {
			return err
		}

		for _, line := range t.InputLines {
			_, err = p.Input.Write([]byte(line + "\n"))
			if err != nil {
				return err
			}
		}
		if err = p.Input.Close(); err != nil {
			return err
		}

		result, err := p.Wait()
		if err != nil {
			message := fmt.Sprintf("Error running Logstash: %s.", err)
			if result.Output != "" {
				message += fmt.Sprintf("\nProcess output:\n%s", result.Output)
			} else {
				message += "\nThe process wrote nothing to stdout or stderr."
			}
			if result.Log != "" {
				message += fmt.Sprintf("\nLog:\n%s", result.Log)
			} else {
				message += "\nThe process wrote nothing to its logfile."
			}
			return errors.New(message)
		}
		if err = t.Compare(result.Events, false, diffCommand); err != nil {
			userError("Testcase failed, continuing with the rest: %s", err.Error())
			ok = false
		}
	}
	if !ok {
		return errors.New("One or more testcases failed.")
	}
	return nil
}