blob: 9ac70a27461527f31016c049605339683bc75e45 [file]
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package jars contains functionality for running jars for integration tests. The main entry point
// for running a jar is the Run function. The Process interface is used to interact with the running
// jars, and most importantly for shutting down the jars once finished with them.
package jars
import (
"fmt"
"os/exec"
"time"
)
type runCallback func(dur time.Duration, jar string, args ...string) (Process, error)
var runner runCallback // Saves which behavior to use when Run is called.
func init() {
runner = getRunner()
}
// getRunner is used to determine the appropriate behavior for run during initialization time,
// based on the OS and installed binaries of the system. This is returned as a runCallback which
// can be called whenever Run is called. If an error prevents Run from being used at all (for
// example, Java is not installed), then the runCallback will return that error.
func getRunner() runCallback {
// First check if we can even run jars.
_, err := exec.LookPath("java")
if err != nil {
err := fmt.Errorf("cannot run jar: 'java' command not installed: %w", err)
return func(_ time.Duration, _ string, _ ...string) (Process, error) {
return nil, err
}
}
// Defer to OS-specific logic for checking for presence of timeout command.
return getTimeoutRunner()
}
// Run runs a jar given an optional duration, a path to the jar, and any desired arguments to the
// jar. It returns a Process object which can be used to shut down the jar once finished.
//
// The dur parameter is a duration for the timeout command which can be used to automatically kill
// the jar after a set duration, in order to avoid resource leakage. Timeout is described here:
// https://man7.org/linux/man-pages/man1/timeout.1.html. Durations will be translated from
// time.Duration to a string based on the number of minutes. If a duration is provided but the
// system is unable to use the timeout is unable to use the timeout command, this function will
// return an error. To indicate that a duration isn't needed, pass in 0.
func Run(dur time.Duration, jar string, args ...string) (Process, error) {
return runner(dur, jar, args...)
}