-
Notifications
You must be signed in to change notification settings - Fork 186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[full-ci][tests-only]Add support to stop and start service in ociswrapper #10776
base: master
Are you sure you want to change the base?
Changes from all commits
22b981c
ae33ea7
6c02b0b
ca283c8
d7778d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -191,6 +191,24 @@ public function theConfigHasBeenSetToValue(TableNode $table): void { | |||||||||
); | ||||||||||
} | ||||||||||
|
||||||||||
/** | ||||||||||
* @Given the ocis server has started service :service separately | ||||||||||
* | ||||||||||
* @param string $service | ||||||||||
* | ||||||||||
* @return void | ||||||||||
* @throws GuzzleException | ||||||||||
*/ | ||||||||||
public function theOcisServerHasStartedServiceSeparately(string $service) { | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
$response = OcisConfigHelper::startService($service); | ||||||||||
|
||||||||||
Assert::assertEquals( | ||||||||||
200, | ||||||||||
$response->getStatusCode(), | ||||||||||
"Failed to start service $service." | ||||||||||
); | ||||||||||
} | ||||||||||
|
||||||||||
/** | ||||||||||
* @AfterScenario @env-config | ||||||||||
* | ||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -113,7 +113,7 @@ Feature: service health check | |
Then the HTTP status code of responses on all endpoints should be "200" | ||
|
||
@issue-10661 | ||
Scenario: check default services readiness | ||
Scenario: check default services readiness (graph, idp, proxy) | ||
When a user requests these URLs with "GET" and no authentication | ||
| endpoint | service | | ||
| http://%base_url_hostname%:9124/readyz | graph | | ||
|
@@ -122,7 +122,7 @@ Feature: service health check | |
Then the HTTP status code of responses on all endpoints should be "200" | ||
|
||
@env-config @issue-10661 | ||
Scenario: check extra services readiness | ||
Scenario: check auth-bearer service readiness | ||
Given the following configs have been set: | ||
| config | value | | ||
| OCIS_ADD_RUN_SERVICES | auth-bearer | | ||
|
@@ -131,3 +131,11 @@ Feature: service health check | |
| endpoint | service | | ||
| http://%base_url_hostname%:9149/readyz | auth-bearer | | ||
Then the HTTP status code of responses on all endpoints should be "200" | ||
|
||
@env-config | ||
Scenario: check services health while running separately | ||
Given the ocis server has started service "storage-users" separately | ||
When a user requests these URLs with "GET" and no authentication | ||
| endpoint | service | | ||
| http://%base_url_hostname%:9159/healthz | storage-users | | ||
Then the HTTP status code of responses on all endpoints should be "200" | ||
Comment on lines
+135
to
+141
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this a debug scenario? |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -26,110 +26,21 @@ var cmd *exec.Cmd | |||||||
var retryCount = 0 | ||||||||
var stopSignal = false | ||||||||
var EnvConfigs = []string{} | ||||||||
var runningServices = make(map[string]int) | ||||||||
|
||||||||
func Start(envMap []string) { | ||||||||
// wait for the log scanner to finish | ||||||||
var wg sync.WaitGroup | ||||||||
wg.Add(2) | ||||||||
|
||||||||
stopSignal = false | ||||||||
if retryCount == 0 { | ||||||||
defer common.Wg.Done() | ||||||||
} | ||||||||
|
||||||||
cmd = exec.Command(config.Get("bin"), "server") | ||||||||
if envMap == nil { | ||||||||
cmd.Env = append(os.Environ(), EnvConfigs...) | ||||||||
} else { | ||||||||
cmd.Env = append(os.Environ(), envMap...) | ||||||||
} | ||||||||
|
||||||||
logs, err := cmd.StderrPipe() | ||||||||
if err != nil { | ||||||||
log.Panic(err) | ||||||||
} | ||||||||
output, err := cmd.StdoutPipe() | ||||||||
if err != nil { | ||||||||
log.Panic(err) | ||||||||
} | ||||||||
|
||||||||
err = cmd.Start() | ||||||||
if err != nil { | ||||||||
log.Panic(err) | ||||||||
} | ||||||||
|
||||||||
logScanner := bufio.NewScanner(logs) | ||||||||
outputScanner := bufio.NewScanner(output) | ||||||||
outChan := make(chan string) | ||||||||
|
||||||||
// Read the logs when the 'ocis server' command is running | ||||||||
go func() { | ||||||||
defer wg.Done() | ||||||||
for logScanner.Scan() { | ||||||||
outChan <- logScanner.Text() | ||||||||
} | ||||||||
}() | ||||||||
|
||||||||
go func() { | ||||||||
defer wg.Done() | ||||||||
for outputScanner.Scan() { | ||||||||
outChan <- outputScanner.Text() | ||||||||
} | ||||||||
}() | ||||||||
|
||||||||
// Fetch logs from the channel and print them | ||||||||
go func() { | ||||||||
for s := range outChan { | ||||||||
fmt.Println(s) | ||||||||
} | ||||||||
}() | ||||||||
|
||||||||
if err := cmd.Wait(); err != nil { | ||||||||
if exitErr, ok := err.(*exec.ExitError); ok { | ||||||||
status := exitErr.Sys().(syscall.WaitStatus) | ||||||||
// retry only if oCIS server exited with code > 0 | ||||||||
// -1 exit code means that the process was killed by a signal (syscall.SIGINT) | ||||||||
if status.ExitStatus() > 0 && !stopSignal { | ||||||||
waitUntilCompleteShutdown() | ||||||||
|
||||||||
log.Println(fmt.Sprintf("oCIS server exited with code %v", status.ExitStatus())) | ||||||||
|
||||||||
// retry to start oCIS server | ||||||||
retryCount++ | ||||||||
maxRetry, _ := strconv.Atoi(config.Get("retry")) | ||||||||
if retryCount <= maxRetry { | ||||||||
wg.Wait() | ||||||||
close(outChan) | ||||||||
log.Println(fmt.Sprintf("Retry starting oCIS server... (retry %v)", retryCount)) | ||||||||
// wait 500 milliseconds before retrying | ||||||||
time.Sleep(500 * time.Millisecond) | ||||||||
Start(envMap) | ||||||||
return | ||||||||
} | ||||||||
} | ||||||||
} | ||||||||
} | ||||||||
wg.Wait() | ||||||||
close(outChan) | ||||||||
log.Println("Starting oCIS service........\n") | ||||||||
StartService("", envMap) | ||||||||
} | ||||||||
|
||||||||
func Stop() (bool, string) { | ||||||||
log.Println("Stopping oCIS server...") | ||||||||
stopSignal = true | ||||||||
|
||||||||
if cmd == nil { | ||||||||
return true, "oCIS server is not running" | ||||||||
for service := range runningServices { | ||||||||
go StopService(service) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this needs to be waited |
||||||||
} | ||||||||
|
||||||||
err := cmd.Process.Signal(syscall.SIGINT) | ||||||||
if err != nil { | ||||||||
if !strings.HasSuffix(err.Error(), "process already finished") { | ||||||||
log.Fatalln(err) | ||||||||
} else { | ||||||||
return true, "oCIS server is already stopped" | ||||||||
} | ||||||||
} | ||||||||
cmd.Process.Wait() | ||||||||
success, message := waitUntilCompleteShutdown() | ||||||||
|
||||||||
cmd = nil | ||||||||
|
@@ -147,10 +58,16 @@ func Restart(envMap []string) (bool, string) { | |||||||
} | ||||||||
|
||||||||
func IsOcisRunning() bool { | ||||||||
if cmd != nil { | ||||||||
return cmd.Process.Pid > 0 | ||||||||
if runningServices["ocis"] == 0 { | ||||||||
return false | ||||||||
} | ||||||||
return false | ||||||||
|
||||||||
_, err := os.FindProcess(runningServices["ocis"]) | ||||||||
if err != nil { | ||||||||
delete(runningServices, "ocis") | ||||||||
return false | ||||||||
} | ||||||||
return true | ||||||||
} | ||||||||
|
||||||||
func waitAllServices(startTime time.Time, timeout time.Duration) { | ||||||||
|
@@ -271,3 +188,131 @@ func RunCommand(command string, inputs []string) (int, string) { | |||||||
|
||||||||
return c.ProcessState.ExitCode(), cmdOutput | ||||||||
} | ||||||||
|
||||||||
func StartService(service string, envMap []string) { | ||||||||
// Initialize command args based on service presence | ||||||||
cmdArgs := []string{"server"} // Default command args | ||||||||
|
||||||||
if service != "" { | ||||||||
cmdArgs = append([]string{service}, cmdArgs...) | ||||||||
} | ||||||||
|
||||||||
var wg sync.WaitGroup | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
wg.Add(2) | ||||||||
|
||||||||
stopSignal = false | ||||||||
if retryCount == 0 { | ||||||||
defer common.Wg.Done() | ||||||||
} | ||||||||
|
||||||||
cmd = exec.Command(config.Get("bin"), cmdArgs...) | ||||||||
|
||||||||
if len(envMap) == 0 { | ||||||||
cmd.Env = append(os.Environ(), EnvConfigs...) | ||||||||
} else { | ||||||||
cmd.Env = append(os.Environ(), envMap...) | ||||||||
} | ||||||||
|
||||||||
logs, err := cmd.StderrPipe() | ||||||||
if err != nil { | ||||||||
log.Panic(err) | ||||||||
} | ||||||||
output, err := cmd.StdoutPipe() | ||||||||
if err != nil { | ||||||||
log.Panic(err) | ||||||||
} | ||||||||
|
||||||||
err = cmd.Start() | ||||||||
|
||||||||
if err != nil { | ||||||||
log.Panic(err) | ||||||||
} | ||||||||
|
||||||||
logScanner := bufio.NewScanner(logs) | ||||||||
outputScanner := bufio.NewScanner(output) | ||||||||
outChan := make(chan string) | ||||||||
|
||||||||
if service == "" { | ||||||||
runningServices["ocis"] = cmd.Process.Pid | ||||||||
} else { | ||||||||
runningServices[service] = cmd.Process.Pid | ||||||||
} | ||||||||
|
||||||||
for listService, pid := range runningServices { | ||||||||
log.Println(fmt.Sprintf("%s service started with process id %v\n", listService, pid)) | ||||||||
} | ||||||||
|
||||||||
// Read the logs when the 'ocis server' command is running | ||||||||
go func() { | ||||||||
defer wg.Done() | ||||||||
for logScanner.Scan() { | ||||||||
outChan <- logScanner.Text() | ||||||||
} | ||||||||
}() | ||||||||
|
||||||||
go func() { | ||||||||
defer wg.Done() | ||||||||
for outputScanner.Scan() { | ||||||||
outChan <- outputScanner.Text() | ||||||||
} | ||||||||
}() | ||||||||
|
||||||||
// Fetch logs from the channel and print them | ||||||||
go func() { | ||||||||
for s := range outChan { | ||||||||
fmt.Println(s) | ||||||||
} | ||||||||
}() | ||||||||
|
||||||||
if err := cmd.Wait(); err != nil { | ||||||||
if exitErr, ok := err.(*exec.ExitError); ok { | ||||||||
status := exitErr.Sys().(syscall.WaitStatus) | ||||||||
// retry only if oCIS server exited with code > 0 | ||||||||
// -1 exit code means that the process was killed by a signal (syscall.SIGINT) | ||||||||
if status.ExitStatus() > 0 && !stopSignal { | ||||||||
waitUntilCompleteShutdown() | ||||||||
|
||||||||
log.Println(fmt.Sprintf("oCIS server exited with code %v", status.ExitStatus())) | ||||||||
|
||||||||
// retry to start oCIS server | ||||||||
retryCount++ | ||||||||
maxRetry, _ := strconv.Atoi(config.Get("retry")) | ||||||||
if retryCount <= maxRetry { | ||||||||
wg.Wait() | ||||||||
close(outChan) | ||||||||
log.Println(fmt.Sprintf("Retry starting oCIS server... (retry %v)", retryCount)) | ||||||||
// wait 500 milliseconds before retrying | ||||||||
time.Sleep(500 * time.Millisecond) | ||||||||
StartService(service, envMap) | ||||||||
return | ||||||||
} | ||||||||
} | ||||||||
} | ||||||||
} | ||||||||
wg.Wait() | ||||||||
close(outChan) | ||||||||
} | ||||||||
|
||||||||
// Stop oCIS service or a specific service by its unique identifier | ||||||||
func StopService(service string) (bool, string) { | ||||||||
pid, exists := runningServices[service] | ||||||||
if !exists { | ||||||||
return false, fmt.Sprintf("Running service doesn't not include %s service", service) | ||||||||
} | ||||||||
|
||||||||
process, err := os.FindProcess(pid) | ||||||||
if err != nil { | ||||||||
return false, fmt.Sprintf("Failed to find service %s process running with ID %d", service, pid) | ||||||||
} | ||||||||
|
||||||||
pKillError := process.Signal(syscall.SIGINT) | ||||||||
if pKillError != nil { | ||||||||
return false, fmt.Sprintf("Failed to stop service with process id %d", pid) | ||||||||
} else { | ||||||||
delete(runningServices, service) | ||||||||
|
||||||||
log.Println(fmt.Sprintf("oCIS service %s has been stopped successfully", service)) | ||||||||
} | ||||||||
|
||||||||
return true, fmt.Sprintf("Service %s stopped successfully", service) | ||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.