github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/tests/rkt_pid_file_test.go (about) 1 // Copyright 2015 The rkt Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "fmt" 19 "os" 20 "os/exec" 21 "path/filepath" 22 "strings" 23 "testing" 24 "time" 25 26 "github.com/coreos/rkt/Godeps/_workspace/src/github.com/steveeJ/gexpect" 27 "github.com/coreos/rkt/tests/testutils" 28 ) 29 30 func preparePidFileRace(t *testing.T, ctx *testutils.RktRunCtx, sleepImage string) (*gexpect.ExpectSubprocess, *gexpect.ExpectSubprocess, string, string) { 31 // Start the pod 32 runCmd := fmt.Sprintf("%s --debug --insecure-skip-verify run --mds-register=false --interactive %s", ctx.Cmd(), sleepImage) 33 runChild := spawnOrFail(t, runCmd) 34 35 if err := expectWithOutput(runChild, "Enter text:"); err != nil { 36 t.Fatalf("Waited for the prompt but not found: %v", err) 37 } 38 39 // Check the ppid file is really created 40 cmd := fmt.Sprintf(`%s list --full|grep running`, ctx.Cmd()) 41 output, err := exec.Command("/bin/sh", "-c", cmd).CombinedOutput() 42 if err != nil { 43 t.Fatalf("Couldn't list the pods: %v", err) 44 } 45 UUID := strings.Split(string(output), "\t")[0] 46 47 pidFileName := filepath.Join(ctx.DataDir(), "pods/run", UUID, "ppid") 48 if _, err := os.Stat(pidFileName); err != nil { 49 t.Fatalf("Pid file missing: %v", err) 50 } 51 52 // Temporarily move the ppid file away 53 pidFileNameBackup := pidFileName + ".backup" 54 if err := os.Rename(pidFileName, pidFileNameBackup); err != nil { 55 t.Fatalf("Cannot move ppid file away: %v", err) 56 } 57 58 // Start the "enter" command without the pidfile 59 enterCmd := fmt.Sprintf("%s --debug enter %s /inspect --print-msg=RktEnterWorksFine", ctx.Cmd(), UUID) 60 t.Logf("%s", enterCmd) 61 enterChild := spawnOrFail(t, enterCmd) 62 63 // Enter should be able to wait until the ppid file appears 64 time.Sleep(1 * time.Second) 65 66 return runChild, enterChild, pidFileName, pidFileNameBackup 67 } 68 69 // Check that "enter" is able to wait for the ppid file to be created 70 func TestPidFileDelayedStart(t *testing.T) { 71 sleepImage := patchTestACI("rkt-inspect-sleep.aci", "--exec=/inspect --read-stdin") 72 defer os.Remove(sleepImage) 73 74 ctx := testutils.NewRktRunCtx() 75 defer ctx.Cleanup() 76 77 runChild, enterChild, pidFileName, pidFileNameBackup := preparePidFileRace(t, ctx, sleepImage) 78 79 // Restore ppid file so the "enter" command can find it 80 if err := os.Rename(pidFileNameBackup, pidFileName); err != nil { 81 t.Fatalf("Cannot restore ppid file: %v", err) 82 } 83 84 // Now the "enter" command works and can complete 85 if err := expectWithOutput(enterChild, "RktEnterWorksFine"); err != nil { 86 t.Fatalf("Waited for enter to works but failed: %v", err) 87 } 88 if err := enterChild.Wait(); err != nil { 89 t.Fatalf("rkt enter didn't terminate correctly: %v", err) 90 } 91 92 // Terminate the pod 93 if err := runChild.SendLine("Bye"); err != nil { 94 t.Fatalf("rkt couldn't write to the container: %v", err) 95 } 96 if err := expectWithOutput(runChild, "Received text: Bye"); err != nil { 97 t.Fatalf("Expected Bye but not found: %v", err) 98 } 99 if err := runChild.Wait(); err != nil { 100 t.Fatalf("rkt didn't terminate correctly: %v", err) 101 } 102 } 103 104 // Check that "enter" doesn't wait forever for the ppid file when the pod is terminated 105 func TestPidFileAbortedStart(t *testing.T) { 106 sleepImage := patchTestACI("rkt-inspect-sleep.aci", "--exec=/inspect --read-stdin") 107 defer os.Remove(sleepImage) 108 109 ctx := testutils.NewRktRunCtx() 110 defer ctx.Cleanup() 111 112 runChild, enterChild, _, _ := preparePidFileRace(t, ctx, sleepImage) 113 114 // Terminate the pod with the escape sequence: ^]^]^] 115 if err := runChild.SendLine("\035\035\035"); err != nil { 116 t.Fatalf("Failed to terminate the pod: %v", err) 117 } 118 waitOrFail(t, runChild, false) 119 120 // Now the "enter" command terminates quickly 121 before := time.Now() 122 if err := enterChild.Wait(); err.Error() != "exit status 1" { 123 t.Fatalf("rkt enter didn't terminate as expected: %v", err) 124 } 125 delay := time.Now().Sub(before) 126 t.Logf("rkt enter terminated %v after the pod was terminated", delay) 127 if delay > time.Second { // 1 second shall be enough: it takes less than 50ms on my computer 128 t.Fatalf("rkt enter didn't terminate quickly enough: %v", delay) 129 } 130 131 }