github.com/coreos/mantle@v0.13.0/network/journal/record_test.go (about) 1 // Copyright 2017 CoreOS, Inc. 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 journal 16 17 import ( 18 "context" 19 "io" 20 "io/ioutil" 21 "strings" 22 "testing" 23 "time" 24 25 "github.com/coreos/mantle/network/mockssh" 26 ) 27 28 const ( 29 // cursor strings for exportText and exportBinary from export_test.go 30 cursorText = "s=739ad463348b4ceca5a9e69c95a3c93f;i=4ece8;b=6c7c6013a26343b29e964691ff25d04c;m=4fc72572f;t=4c508a7243799;x=68597058a89b7246;p=system.journal" 31 cursorBinary = "s=bcce4fb8ffcb40e9a6e05eee8b7831bf;i=5ef603;b=ec25d6795f0645619ddac9afdef453ee;m=545242e7049;t=50f1202" 32 33 // commands the recorder should execute 34 journalBoot = "journalctl --output=export --follow --lines=all --boot" 35 journalAfter = "journalctl --output=export --follow --lines=all --after-cursor " // + cursorText or cursorBinary 36 ) 37 38 type nullFormatter struct{} 39 40 func (n nullFormatter) SetTimezone(tz *time.Location) {} 41 42 func (n nullFormatter) WriteEntry(entry Entry) error { 43 return nil 44 } 45 46 type discardCloser struct{} 47 48 func (d discardCloser) Close() error { 49 return nil 50 } 51 52 func (d discardCloser) Write(b []byte) (int, error) { 53 return ioutil.Discard.Write(b) 54 } 55 56 // Escapes ; chars in cursor with \ 57 // May need tweaking if the shellquote library behavior ever changes. 58 func journalAfterEsc(cursor string) string { 59 return journalAfter + strings.Replace(cursor, ";", "\\;", -1) 60 } 61 62 func TestRecorderSSH(t *testing.T) { 63 ctx := context.Background() 64 client := mockssh.NewMockClient(func(s *mockssh.Session) { 65 if s.Exec != journalBoot { 66 t.Errorf("got %q wanted %q", s.Exec, journalBoot) 67 } 68 if _, err := io.WriteString(s.Stdout, exportText); err != nil { 69 t.Error(err) 70 } 71 if err := s.Exit(0); err != nil { 72 t.Error(err) 73 } 74 }) 75 76 recorder := NewRecorder(nullFormatter{}, discardCloser{}) 77 if err := recorder.RunSSH(ctx, client); err != nil { 78 t.Fatal(err) 79 } 80 81 if recorder.cursor != cursorText { 82 t.Errorf("got %q wanted %q", recorder.cursor, cursorText) 83 } 84 85 client = mockssh.NewMockClient(func(s *mockssh.Session) { 86 cmd := journalAfterEsc(cursorText) 87 if s.Exec != cmd { 88 t.Errorf("got %q wanted %q", s.Exec, cmd) 89 } 90 if _, err := io.WriteString(s.Stdout, exportBinary); err != nil { 91 t.Error(err) 92 } 93 if err := s.Exit(0); err != nil { 94 t.Error(err) 95 } 96 }) 97 98 if err := recorder.RunSSH(ctx, client); err != nil { 99 t.Fatal(err) 100 } 101 102 if recorder.cursor != cursorBinary { 103 t.Errorf("got %q wanted %q", recorder.cursor, cursorBinary) 104 } 105 106 client = mockssh.NewMockClient(func(s *mockssh.Session) { 107 cmd := journalAfterEsc(cursorBinary) 108 if s.Exec != cmd { 109 t.Errorf("got %q wanted %q", s.Exec, cmd) 110 } 111 if err := s.Close(); err != nil { 112 t.Error(err) 113 } 114 }) 115 116 if err := recorder.RunSSH(ctx, client); err != nil { 117 t.Fatal(err) 118 } 119 120 if recorder.cursor != cursorBinary { 121 t.Errorf("got %q wanted %q", recorder.cursor, cursorBinary) 122 } 123 } 124 125 func TestRecorderSSHCancel(t *testing.T) { 126 ctx, cancel := context.WithCancel(context.Background()) 127 client := mockssh.NewMockClient(func(s *mockssh.Session) { 128 // Skip close, let the connection hang. 129 }) 130 131 recorder := NewRecorder(nullFormatter{}, discardCloser{}) 132 if err := recorder.StartSSH(ctx, client); err != nil { 133 t.Fatal(err) 134 } 135 136 cancel() 137 138 if err := recorder.Wait(); err != nil { 139 t.Fatal(err) 140 } 141 }