mirror of
https://github.com/opencontainers/runc.git
synced 2025-10-05 15:37:02 +08:00

There were issues where a process could die before pausing completed leaving the container in an inconsistent state and unable to be destoryed. This makes sure that if the container is paused and the process is dead it will unfreeze the cgroup before removing them. Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
80 lines
1.6 KiB
Go
80 lines
1.6 KiB
Go
// +build linux
|
|
|
|
package libcontainer
|
|
|
|
import "testing"
|
|
|
|
func TestStateStatus(t *testing.T) {
|
|
states := map[containerState]Status{
|
|
&stoppedState{}: Destroyed,
|
|
&runningState{}: Running,
|
|
&restoredState{}: Running,
|
|
&pausedState{}: Paused,
|
|
}
|
|
for s, status := range states {
|
|
if s.status() != status {
|
|
t.Fatalf("state returned %s but expected %s", s.status(), status)
|
|
}
|
|
}
|
|
}
|
|
|
|
func isStateTransitionError(err error) bool {
|
|
_, ok := err.(*stateTransitionError)
|
|
return ok
|
|
}
|
|
|
|
func TestStoppedStateTransition(t *testing.T) {
|
|
s := &stoppedState{c: &linuxContainer{}}
|
|
valid := []containerState{
|
|
&stoppedState{},
|
|
&runningState{},
|
|
&restoredState{},
|
|
}
|
|
for _, v := range valid {
|
|
if err := s.transition(v); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
err := s.transition(&pausedState{})
|
|
if err == nil {
|
|
t.Fatal("transition to paused state should fail")
|
|
}
|
|
if !isStateTransitionError(err) {
|
|
t.Fatal("expected stateTransitionError")
|
|
}
|
|
}
|
|
|
|
func TestPausedStateTransition(t *testing.T) {
|
|
s := &pausedState{c: &linuxContainer{}}
|
|
valid := []containerState{
|
|
&pausedState{},
|
|
&runningState{},
|
|
&stoppedState{},
|
|
}
|
|
for _, v := range valid {
|
|
if err := s.transition(v); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRestoredStateTransition(t *testing.T) {
|
|
s := &restoredState{c: &linuxContainer{}}
|
|
valid := []containerState{
|
|
&stoppedState{},
|
|
&runningState{},
|
|
}
|
|
for _, v := range valid {
|
|
if err := s.transition(v); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
err := s.transition(&nullState{})
|
|
if err == nil {
|
|
t.Fatal("transition to null state should fail")
|
|
}
|
|
if !isStateTransitionError(err) {
|
|
t.Fatal("expected stateTransitionError")
|
|
}
|
|
}
|