-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[core] test environment's FSM, handling hooks and fix discovered issues
The fixes being: - set run_end_completion_time_ms also at the end of GO_ERROR transition - document that the ECS does not abort the call execution upon timeout, merely passes the parameter to the call - avoid a crash if the FSM.Event() is called without providing a Transition
- Loading branch information
Showing
11 changed files
with
711 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package environment | ||
|
||
import ( | ||
"github.com/AliceO2Group/Control/core/integration" | ||
"github.com/AliceO2Group/Control/core/integration/testplugin" | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
"github.com/spf13/viper" | ||
"io" | ||
"os" | ||
"testing" | ||
) | ||
|
||
const envTestConfig = "environment_test.yaml" | ||
|
||
var tmpDir *string | ||
|
||
var _ = BeforeSuite(func() { | ||
var err error | ||
tmpDir = new(string) | ||
*tmpDir, err = os.MkdirTemp("", "o2control-core-environment") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
// copy config files | ||
configFiles := []string{envTestConfig} | ||
for _, configFile := range configFiles { | ||
from, err := os.Open("./" + configFile) | ||
Expect(err).NotTo(HaveOccurred()) | ||
defer from.Close() | ||
|
||
to, err := os.OpenFile(*tmpDir+"/"+configFile, os.O_RDWR|os.O_CREATE, 0666) | ||
Expect(err).NotTo(HaveOccurred()) | ||
defer to.Close() | ||
|
||
_, err = io.Copy(to, from) | ||
Expect(err).NotTo(HaveOccurred()) | ||
} | ||
|
||
viper.Set("coreWorkingDir", tmpDir) // used by NewRunNumber with YAML backend | ||
|
||
integration.Reset() | ||
integration.RegisterPlugin("testplugin", "testPluginEndpoint", testplugin.NewPlugin) | ||
viper.Reset() | ||
viper.Set("integrationPlugins", []string{"testplugin"}) | ||
viper.Set("testPluginEndpoint", "http://example.com") | ||
viper.Set("config_endpoint", "file://"+*tmpDir+"/"+envTestConfig) | ||
}) | ||
|
||
func TestCoreEnvironment(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "Core Environment Test Suite") | ||
} | ||
|
||
var _ = AfterSuite(func() { | ||
os.RemoveAll(*tmpDir) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# the contents of this file are not really used, but we need an apricot instance for environment test package, which needs a non-empty file | ||
o2: | ||
components: | ||
qc: | ||
TECHNICAL: | ||
any: | ||
entry: "config" | ||
runtime: | ||
aliecs: | ||
defaults: | ||
key1: value1 | ||
vars: | ||
key2: value2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package environment | ||
|
||
import ( | ||
"github.com/AliceO2Group/Control/common/utils/uid" | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
var _ = Describe("allowed states and transitions in the environment FSM", func() { | ||
var env *Environment | ||
BeforeEach(func() { | ||
envId, err := uid.FromString("2oDvieFrVTi") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
env, err = newEnvironment(nil, envId) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(env).NotTo(BeNil()) | ||
}) | ||
When("FSM is created", func() { | ||
It("should be in STANDBY", func() { | ||
Expect(env.Sm.Current()).To(Equal("STANDBY")) | ||
}) | ||
}) | ||
When("FSM is in STANDBY", func() { | ||
It("should allow for DEPLOY, GO_ERROR and EXIT transitions", func() { | ||
env.Sm.SetState("STANDBY") | ||
Expect(env.Sm.Can("DEPLOY")).To(BeTrue()) | ||
Expect(env.Sm.Can("GO_ERROR")).To(BeTrue()) | ||
Expect(env.Sm.Can("EXIT")).To(BeTrue()) | ||
}) | ||
It("should not allow for other transitions", func() { | ||
env.Sm.SetState("STANDBY") | ||
Expect(env.Sm.Cannot("CONFIGURE")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("RESET")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("START_ACTIVITY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("STOP_ACTIVITY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("RECOVER")).To(BeTrue()) | ||
}) | ||
}) | ||
When("FSM is in DEPLOYED", func() { | ||
It("should allow for CONFIGURED, GO_ERROR and EXIT transitions", func() { | ||
env.Sm.SetState("DEPLOYED") | ||
Expect(env.Sm.Can("CONFIGURE")).To(BeTrue()) | ||
Expect(env.Sm.Can("GO_ERROR")).To(BeTrue()) | ||
Expect(env.Sm.Can("EXIT")).To(BeTrue()) | ||
}) | ||
It("should not allow for other transitions", func() { | ||
env.Sm.SetState("DEPLOYED") | ||
Expect(env.Sm.Cannot("DEPLOY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("RESET")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("START_ACTIVITY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("STOP_ACTIVITY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("RECOVER")).To(BeTrue()) | ||
}) | ||
}) | ||
When("FSM is in CONFIGURED", func() { | ||
It("should allow for START_ACTIVITY, RESET, GO_ERROR and EXIT transitions", func() { | ||
env.Sm.SetState("CONFIGURED") | ||
Expect(env.Sm.Can("START_ACTIVITY")).To(BeTrue()) | ||
Expect(env.Sm.Can("RESET")).To(BeTrue()) | ||
Expect(env.Sm.Can("GO_ERROR")).To(BeTrue()) | ||
Expect(env.Sm.Can("EXIT")).To(BeTrue()) | ||
}) | ||
It("should not allow for other transitions", func() { | ||
env.Sm.SetState("CONFIGURED") | ||
Expect(env.Sm.Cannot("DEPLOY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("CONFIGURE")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("STOP_ACTIVITY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("RECOVER")).To(BeTrue()) | ||
}) | ||
}) | ||
When("FSM is in RUNNING", func() { | ||
It("should allow for STOP_ACTIVITY and GO_ERROR transitions", func() { | ||
env.Sm.SetState("RUNNING") | ||
Expect(env.Sm.Can("STOP_ACTIVITY")).To(BeTrue()) | ||
Expect(env.Sm.Can("GO_ERROR")).To(BeTrue()) | ||
}) | ||
It("should not allow for other transitions", func() { | ||
env.Sm.SetState("RUNNING") | ||
Expect(env.Sm.Cannot("DEPLOY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("RESET")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("CONFIGURE")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("START_ACTIVITY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("RECOVER")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("EXIT")).To(BeTrue()) | ||
}) | ||
}) | ||
When("FSM is in ERROR", func() { | ||
It("should allow for RECOVER transition", func() { | ||
env.Sm.SetState("ERROR") | ||
Expect(env.Sm.Can("RECOVER")).To(BeTrue()) | ||
// We do not include EXIT as possible transition, since anyway we kill tasks not caring about the FSM. | ||
// There is no known issue which could forbid us from that. | ||
// TEARDOWN and DESTROY are the artificial transitions which correspond to that. | ||
}) | ||
It("should not allow for other transitions", func() { | ||
env.Sm.SetState("ERROR") | ||
Expect(env.Sm.Cannot("GO_ERROR")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("DEPLOY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("RESET")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("CONFIGURE")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("START_ACTIVITY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("STOP_ACTIVITY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("EXIT")).To(BeTrue()) | ||
}) | ||
}) | ||
When("FSM is in DONE", func() { | ||
It("should not allow for any transitions", func() { | ||
env.Sm.SetState("DONE") | ||
Expect(env.Sm.Cannot("GO_ERROR")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("DEPLOY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("RESET")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("CONFIGURE")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("START_ACTIVITY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("STOP_ACTIVITY")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("RECOVER")).To(BeTrue()) | ||
Expect(env.Sm.Cannot("EXIT")).To(BeTrue()) | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.