Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
functional: add TestReplaceSerialization test to assert serialization…
Browse files Browse the repository at this point in the history
… of directives

This tests asserts that systemd directives are serialized when we
transit from the old version of the unit to the new one. Make sure that
ExecStartPre of the new one are executed after ExecStopPost of the
previous one.
  • Loading branch information
Djalal Harouni committed Apr 22, 2016
1 parent 9dfa2ef commit eb6ef52
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
5 changes: 5 additions & 0 deletions functional/fixtures/units/replace-sync.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[Service]
ExecStartPre=/bin/bash -c "echo 'sync'"
ExecStart=/bin/bash -c "while true; do echo Hello, World!; sleep 1; done"
ExecStop=/bin/bash -c "echo 'stopping'"
ExecStopPost=/bin/bash -c "sleep 3; touch /tmp/fleetSyncFile"
76 changes: 76 additions & 0 deletions functional/unit_action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -717,3 +717,79 @@ func replaceUnitMultiple(cmd string, n int) error {

return nil
}

// TestReplaceSerialization tests if the ExecStartPre of the new version
// of the unit when it replaces the old one is excuted after
// ExecStopPost of the old version.
// This test is to make sure that two versions of the same unit will not
// conflict with each other, that the directives are always serialized,
// and it tries its best to avoid the following scenarios:
// https://github.com/coreos/fleet/issues/1000
// https://github.com/systemd/systemd/issues/518
// Now we can't guarantee that that behaviour will not be triggered by
// another external operation, but at least from the Unit replace
// feature context we try to avoid it.
func TestReplaceSerialization(t *testing.T) {
cluster, err := platform.NewNspawnCluster("smoke")
if err != nil {
t.Fatal(err)
}
defer cluster.Destroy()

m, err := cluster.CreateMember()
if err != nil {
t.Fatal(err)
}

_, err = cluster.WaitForNMachines(m, 1)
if err != nil {
t.Fatal(err)
}

tmpSyncFile := "/tmp/fleetSyncReplaceFile"
syncOld := "echo 'sync'"
syncNew := fmt.Sprintf("test -f %s", tmpSyncFile)
tmpSyncService := "/tmp/replace-sync.service"
syncService := "fixtures/units/replace-sync.service"

stdout, stderr, err := cluster.Fleetctl(m, "start", syncService)
if err != nil {
t.Fatalf("Unable to start fleet unit: \nstdout: %s\nstderr: %s\nerr: %v", stdout, stderr, err)
}

_, err = cluster.WaitForNActiveUnits(m, 1)
if err != nil {
t.Fatal(err)
}

// replace the unit content, make sure that:
// It shows up and it did 'stat /tmp/fleetSyncFile' correctly
err = util.GenNewFleetService(tmpSyncService, syncService, syncNew, syncOld)
if err != nil {
t.Fatalf("Failed to generate a temp fleet service: %v", err)
}

stdout, stderr, err = cluster.Fleetctl(m, "start", "--replace", tmpSyncService)
if err != nil {
t.Fatalf("Failed to replace fleet unit: \nstdout: %s\nstderr: %s\nerr: %v", stdout, stderr, err)
}

_, err = cluster.WaitForNActiveUnits(m, 1)
if err != nil {
t.Fatalf("Did not find 1 unit in cluster, unit replace failed: %v", err)
}

tmpService := path.Base(tmpSyncService)
stdout, _ = cluster.MemberCommand(m, "systemctl", "show", "--property=ActiveState", tmpService)
if strings.TrimSpace(stdout) != "ActiveState=active" {
t.Fatalf("Fleet unit not reported as active: %s", stdout)
}

stdout, _ = cluster.MemberCommand(m, "systemctl", "show", "--property=Result", tmpService)
if strings.TrimSpace(stdout) != "Result=success" {
t.Fatalf("Result for fleet unit not reported as success: %s", stdout)
}

os.Remove(tmpSyncFile)
os.Remove(tmpSyncService)
}

0 comments on commit eb6ef52

Please sign in to comment.