loom-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.gitignore +1 -0
 - data/.rspec +2 -0
 - data/Gemfile +4 -0
 - data/Gemfile.lock +99 -0
 - data/Guardfile +54 -0
 - data/Rakefile +6 -0
 - data/bin/loom +185 -0
 - data/lib/env/development.rb +1 -0
 - data/lib/loom.rb +44 -0
 - data/lib/loom/all.rb +20 -0
 - data/lib/loom/config.rb +106 -0
 - data/lib/loom/core_ext.rb +37 -0
 - data/lib/loom/dsl.rb +60 -0
 - data/lib/loom/facts.rb +13 -0
 - data/lib/loom/facts/all.rb +2 -0
 - data/lib/loom/facts/fact_file_provider.rb +86 -0
 - data/lib/loom/facts/fact_set.rb +138 -0
 - data/lib/loom/host_spec.rb +32 -0
 - data/lib/loom/inventory.rb +124 -0
 - data/lib/loom/logger.rb +141 -0
 - data/lib/loom/method_signature.rb +174 -0
 - data/lib/loom/mods.rb +4 -0
 - data/lib/loom/mods/action_proxy.rb +105 -0
 - data/lib/loom/mods/all.rb +3 -0
 - data/lib/loom/mods/mod_loader.rb +80 -0
 - data/lib/loom/mods/module.rb +113 -0
 - data/lib/loom/pattern.rb +15 -0
 - data/lib/loom/pattern/all.rb +7 -0
 - data/lib/loom/pattern/definition_context.rb +74 -0
 - data/lib/loom/pattern/dsl.rb +176 -0
 - data/lib/loom/pattern/hook.rb +28 -0
 - data/lib/loom/pattern/loader.rb +48 -0
 - data/lib/loom/pattern/reference.rb +71 -0
 - data/lib/loom/pattern/reference_set.rb +169 -0
 - data/lib/loom/pattern/result_reporter.rb +77 -0
 - data/lib/loom/runner.rb +209 -0
 - data/lib/loom/shell.rb +12 -0
 - data/lib/loom/shell/all.rb +10 -0
 - data/lib/loom/shell/api.rb +48 -0
 - data/lib/loom/shell/cmd_result.rb +33 -0
 - data/lib/loom/shell/cmd_wrapper.rb +164 -0
 - data/lib/loom/shell/core.rb +226 -0
 - data/lib/loom/shell/harness_blob.rb +26 -0
 - data/lib/loom/shell/harness_command_builder.rb +50 -0
 - data/lib/loom/shell/session.rb +25 -0
 - data/lib/loom/trap.rb +44 -0
 - data/lib/loom/version.rb +3 -0
 - data/lib/loomext/all.rb +4 -0
 - data/lib/loomext/corefacts.rb +6 -0
 - data/lib/loomext/corefacts/all.rb +8 -0
 - data/lib/loomext/corefacts/facter_provider.rb +24 -0
 - data/lib/loomext/coremods.rb +5 -0
 - data/lib/loomext/coremods/all.rb +13 -0
 - data/lib/loomext/coremods/exec.rb +50 -0
 - data/lib/loomext/coremods/files.rb +104 -0
 - data/lib/loomext/coremods/net.rb +33 -0
 - data/lib/loomext/coremods/package/adapter.rb +100 -0
 - data/lib/loomext/coremods/package/package.rb +62 -0
 - data/lib/loomext/coremods/user.rb +82 -0
 - data/lib/loomext/coremods/vm.rb +0 -0
 - data/lib/loomext/coremods/vm/all.rb +6 -0
 - data/lib/loomext/coremods/vm/vbox.rb +84 -0
 - data/loom.gemspec +39 -0
 - data/loom/inventory.yml +13 -0
 - data/scripts/harness.sh +242 -0
 - data/spec/loom/host_spec_spec.rb +101 -0
 - data/spec/loom/inventory_spec.rb +154 -0
 - data/spec/loom/method_signature_spec.rb +275 -0
 - data/spec/loom/pattern/dsl_spec.rb +207 -0
 - data/spec/loom/shell/cmd_wrapper_spec.rb +239 -0
 - data/spec/loom/shell/harness_blob_spec.rb +42 -0
 - data/spec/loom/shell/harness_command_builder_spec.rb +36 -0
 - data/spec/runloom.sh +35 -0
 - data/spec/scripts/harness_spec.rb +385 -0
 - data/spec/spec_helper.rb +94 -0
 - data/spec/test.loom +370 -0
 - data/spec/test_loom_spec.rb +57 -0
 - metadata +287 -0
 
| 
         @@ -0,0 +1,207 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "loom/facts"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "loom/pattern"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "loom/shell"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe Loom::Pattern::DSL do
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              # Fake API for tests. This object should raise an error on any command
         
     | 
| 
      
 8 
     | 
    
         
            +
              # execution.
         
     | 
| 
      
 9 
     | 
    
         
            +
              let(:fake_shell) { Loom::Shell::FakeApi.new }
         
     | 
| 
      
 10 
     | 
    
         
            +
              let(:a_fact_set) do
         
     | 
| 
      
 11 
     | 
    
         
            +
                Loom::Facts::FactSet.new('fake.host', :fact_one => 1, :fact_two => :two)
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              before do
         
     | 
| 
      
 15 
     | 
    
         
            +
                # bit buckets the logs
         
     | 
| 
      
 16 
     | 
    
         
            +
                @logger_io = StringIO.new
         
     | 
| 
      
 17 
     | 
    
         
            +
                Loom.configure do |config|
         
     | 
| 
      
 18 
     | 
    
         
            +
                  config.log_device = @logger_io
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                @reference_set = Loom::Pattern::ReferenceSet::Builder
         
     | 
| 
      
 22 
     | 
    
         
            +
                  .create(loom_file, ':loom_file')
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              let(:pattern_under_test) { @reference_set['pattern_under_test'] }
         
     | 
| 
      
 26 
     | 
    
         
            +
              let(:inner_pattern) { @reference_set['inner:an_inner_pattern'] }
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              context "pattern basics" do
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                let(:loom_file) do
         
     | 
| 
      
 31 
     | 
    
         
            +
            <<EOS
         
     | 
| 
      
 32 
     | 
    
         
            +
              desc "a description of pattern_under_test"
         
     | 
| 
      
 33 
     | 
    
         
            +
              pattern :pattern_under_test do |loom, facts|
         
     | 
| 
      
 34 
     | 
    
         
            +
                loom.do_outer_thing
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              module Inner
         
     | 
| 
      
 38 
     | 
    
         
            +
                include Loom::Pattern
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                desc "an inner pattern"
         
     | 
| 
      
 41 
     | 
    
         
            +
                pattern :an_inner_pattern do |loom, facts|
         
     | 
| 
      
 42 
     | 
    
         
            +
                  loom.do_inner_thing
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
            EOS
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                it "defines a Pattern::Reference" do
         
     | 
| 
      
 49 
     | 
    
         
            +
                  expect(pattern_under_test).to be_a Loom::Pattern::Reference
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                it "defines a reference with a desc" do
         
     | 
| 
      
 53 
     | 
    
         
            +
                  expect(pattern_under_test.desc).to(
         
     | 
| 
      
 54 
     | 
    
         
            +
                    eql "a description of pattern_under_test")
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                it "defines an inner reference with a desc" do
         
     | 
| 
      
 58 
     | 
    
         
            +
                  expect(inner_pattern.desc).to eql "an inner pattern"
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                it "is runnable" do
         
     | 
| 
      
 62 
     | 
    
         
            +
                  pattern_under_test.call fake_shell, a_fact_set
         
     | 
| 
      
 63 
     | 
    
         
            +
                  expect(fake_shell.cmd_executions.first).to be :do_outer_thing
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
              end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              context "#let" do
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                let(:loom_file) do
         
     | 
| 
      
 70 
     | 
    
         
            +
            <<EOS
         
     | 
| 
      
 71 
     | 
    
         
            +
              let(:let_var_1) { "let var 1"}
         
     | 
| 
      
 72 
     | 
    
         
            +
              let(:let_var_2) { "let var 2"}
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              desc "a description of pattern_under_test"
         
     | 
| 
      
 75 
     | 
    
         
            +
              pattern :pattern_under_test do |loom, facts|
         
     | 
| 
      
 76 
     | 
    
         
            +
                loom.do_outer_thing(let_var_1, let_var_2)
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
              desc "a pattern that will raise an erorr"
         
     | 
| 
      
 80 
     | 
    
         
            +
              pattern :bogus_pattern do |loom, facts|
         
     | 
| 
      
 81 
     | 
    
         
            +
                loom.do_outer_thing(let_var_3)
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
              module Inner
         
     | 
| 
      
 85 
     | 
    
         
            +
                include Loom::Pattern
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                let(:let_var_2) { "override let var 2"}
         
     | 
| 
      
 88 
     | 
    
         
            +
                let(:let_var_3) { "let var 3"}
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                desc "an inner pattern"
         
     | 
| 
      
 91 
     | 
    
         
            +
                pattern :an_inner_pattern do |loom, facts|
         
     | 
| 
      
 92 
     | 
    
         
            +
                  loom.do_inner_thing(let_var_1, let_var_2, let_var_3)
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
      
 95 
     | 
    
         
            +
            EOS
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                it "defines :let declartions at the top level" do
         
     | 
| 
      
 99 
     | 
    
         
            +
                  pattern_under_test.call fake_shell, a_fact_set
         
     | 
| 
      
 100 
     | 
    
         
            +
                  expect(fake_shell.cmd_execution_args.first).to(
         
     | 
| 
      
 101 
     | 
    
         
            +
                    eql ["let var 1", "let var 2"])
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                it "defines :let declartions at inner scopes, innacessible to outer" do
         
     | 
| 
      
 105 
     | 
    
         
            +
                  expect do
         
     | 
| 
      
 106 
     | 
    
         
            +
                    @reference_set['bogus_pattern'].call fake_shell, a_fact_set
         
     | 
| 
      
 107 
     | 
    
         
            +
                  end.to raise_error /^undefined local variable/
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                it "defines :let declarations at inner scopes, overriding outer scope" do
         
     | 
| 
      
 111 
     | 
    
         
            +
                  inner_pattern.call fake_shell, a_fact_set
         
     | 
| 
      
 112 
     | 
    
         
            +
                  expect(fake_shell.cmd_execution_args.first).to(
         
     | 
| 
      
 113 
     | 
    
         
            +
                    eql ["let var 1", "override let var 2", "let var 3"])
         
     | 
| 
      
 114 
     | 
    
         
            +
                end
         
     | 
| 
      
 115 
     | 
    
         
            +
              end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
              context "#with_facts" do
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                let(:loom_file) do
         
     | 
| 
      
 120 
     | 
    
         
            +
            <<EOS
         
     | 
| 
      
 121 
     | 
    
         
            +
              with_facts :outer_fact => :outer
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
              desc "a description of pattern_under_test"
         
     | 
| 
      
 124 
     | 
    
         
            +
              pattern :pattern_under_test do |loom, facts|
         
     | 
| 
      
 125 
     | 
    
         
            +
                loom.do_outer_thing facts[:outer_fact]
         
     | 
| 
      
 126 
     | 
    
         
            +
              end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
              module Inner
         
     | 
| 
      
 129 
     | 
    
         
            +
                include Loom::Pattern
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                with_facts :inner_fact => :inner
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                desc "an inner pattern"
         
     | 
| 
      
 134 
     | 
    
         
            +
                pattern :an_inner_pattern do |loom, facts|
         
     | 
| 
      
 135 
     | 
    
         
            +
                  loom.do_inner_thing(facts[:outer_fact], facts[:inner_fact])
         
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
      
 137 
     | 
    
         
            +
              end
         
     | 
| 
      
 138 
     | 
    
         
            +
            EOS
         
     | 
| 
      
 139 
     | 
    
         
            +
                end
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                it "defines fact sets at the top level" do
         
     | 
| 
      
 142 
     | 
    
         
            +
                  pattern_under_test.call fake_shell, a_fact_set
         
     | 
| 
      
 143 
     | 
    
         
            +
                  expect(fake_shell.cmd_execution_args.first).to(
         
     | 
| 
      
 144 
     | 
    
         
            +
                    eql [:outer])
         
     | 
| 
      
 145 
     | 
    
         
            +
                end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                it "provides fact sets that get merged into inner modules" do
         
     | 
| 
      
 148 
     | 
    
         
            +
                  inner_pattern.call fake_shell, a_fact_set
         
     | 
| 
      
 149 
     | 
    
         
            +
                  expect(fake_shell.cmd_execution_args.first).to(
         
     | 
| 
      
 150 
     | 
    
         
            +
                    eql [:outer, :inner])
         
     | 
| 
      
 151 
     | 
    
         
            +
                end
         
     | 
| 
      
 152 
     | 
    
         
            +
              end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
              context "hooks" do
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                let(:loom_file) do
         
     | 
| 
      
 157 
     | 
    
         
            +
            <<EOS
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
              let(:hook_order) { [] }
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
              before do hook_order.push("outer before hook") end
         
     | 
| 
      
 162 
     | 
    
         
            +
              after do hook_order.push("outer after hook") end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
              desc "a description of pattern_under_test"
         
     | 
| 
      
 165 
     | 
    
         
            +
              pattern :pattern_under_test do |loom, facts|
         
     | 
| 
      
 166 
     | 
    
         
            +
                hook_order.push "execute the pattern"
         
     | 
| 
      
 167 
     | 
    
         
            +
                loom.do_outer_thing(hook_order)
         
     | 
| 
      
 168 
     | 
    
         
            +
              end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
              module Inner
         
     | 
| 
      
 171 
     | 
    
         
            +
                include Loom::Pattern
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                before do hook_order.push("inner before hook") end
         
     | 
| 
      
 174 
     | 
    
         
            +
                after do hook_order.push("inner after hook") end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                desc "an inner pattern"
         
     | 
| 
      
 177 
     | 
    
         
            +
                pattern :an_inner_pattern do |loom, facts|
         
     | 
| 
      
 178 
     | 
    
         
            +
                  hook_order.push "execute inner pattern"
         
     | 
| 
      
 179 
     | 
    
         
            +
                  loom.do_inner_thing(hook_order)
         
     | 
| 
      
 180 
     | 
    
         
            +
                end
         
     | 
| 
      
 181 
     | 
    
         
            +
              end
         
     | 
| 
      
 182 
     | 
    
         
            +
            EOS
         
     | 
| 
      
 183 
     | 
    
         
            +
                end
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                it "executes outer before hooks first and after hooks last" do
         
     | 
| 
      
 186 
     | 
    
         
            +
                  pattern_under_test.call fake_shell, a_fact_set
         
     | 
| 
      
 187 
     | 
    
         
            +
                  expect(fake_shell.cmd_execution_args.first).to eql [[
         
     | 
| 
      
 188 
     | 
    
         
            +
                    "outer before hook",
         
     | 
| 
      
 189 
     | 
    
         
            +
                    "execute the pattern",
         
     | 
| 
      
 190 
     | 
    
         
            +
                    "outer after hook"
         
     | 
| 
      
 191 
     | 
    
         
            +
                  ]]
         
     | 
| 
      
 192 
     | 
    
         
            +
                end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                it "executes nested hooks in wrapped order" do
         
     | 
| 
      
 195 
     | 
    
         
            +
                  inner_pattern.call fake_shell, a_fact_set
         
     | 
| 
      
 196 
     | 
    
         
            +
                  expect(fake_shell.cmd_execution_args.first).to eql [[
         
     | 
| 
      
 197 
     | 
    
         
            +
                    "outer before hook",
         
     | 
| 
      
 198 
     | 
    
         
            +
                    "inner before hook",
         
     | 
| 
      
 199 
     | 
    
         
            +
                    "execute inner pattern",
         
     | 
| 
      
 200 
     | 
    
         
            +
                    "inner after hook",
         
     | 
| 
      
 201 
     | 
    
         
            +
                    "outer after hook"
         
     | 
| 
      
 202 
     | 
    
         
            +
                  ]]
         
     | 
| 
      
 203 
     | 
    
         
            +
                end
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
              end
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,239 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "loom/shell"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "yaml"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            describe Loom::Shell::CmdWrapper do
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              def unescape_cmd(cmd)
         
     | 
| 
      
 7 
     | 
    
         
            +
                YAML.load(%Q(---\n"#{cmd.to_s}"\n))
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              context "examples" do
         
     | 
| 
      
 11 
     | 
    
         
            +
                it "escapes spaces" do
         
     | 
| 
      
 12 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new :printf, "print out this string"
         
     | 
| 
      
 13 
     | 
    
         
            +
                  expect(%x{#{cmd}}).to eql "print out this string"
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                it "skips escaping symbols and frozen string" do
         
     | 
| 
      
 17 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new :"/bin/echo", :"\"yy\"", "\"xx\""
         
     | 
| 
      
 18 
     | 
    
         
            +
                  expect(%x{#{cmd}}.strip).to eql "yy \"xx\""
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              context ".new" do
         
     | 
| 
      
 23 
     | 
    
         
            +
                it "does not escape whitespace between joined commands parts" do
         
     | 
| 
      
 24 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new :echo, "-n", "\"all the rest\""
         
     | 
| 
      
 25 
     | 
    
         
            +
                  expect(cmd.escape_cmd).to eql "echo -n \\\"all\\ the\\ rest\\\""
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                it "flattens cmd input" do
         
     | 
| 
      
 29 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new :somecmd, ["-f", "file.txt"], [:a, [:b]]
         
     | 
| 
      
 30 
     | 
    
         
            +
                  expect(cmd.to_s).to eql "somecmd -f file.txt a b"
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              context ".escape" do
         
     | 
| 
      
 35 
     | 
    
         
            +
                it "escapes CmdWrappers" do
         
     | 
| 
      
 36 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new '"hi"'
         
     | 
| 
      
 37 
     | 
    
         
            +
                  expect(Loom::Shell::CmdWrapper.escape cmd).to eql cmd.to_s
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                it "escapes recursively" do
         
     | 
| 
      
 41 
     | 
    
         
            +
                  content = 'I said "row row row your boat"'
         
     | 
| 
      
 42 
     | 
    
         
            +
                  cmd_inner = 'echo "%s"' % Loom::Shell::CmdWrapper.escape(content)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  cmd_outer = '"%s"' % Loom::Shell::CmdWrapper.escape(cmd_inner)
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  expected = '"echo\ \"I\\\\\ said\\\\\ ' +
         
     | 
| 
      
 46 
     | 
    
         
            +
                             '\\\\\"row\\\\\ row\\\\\ row\\\\\ your\\\\\ boat\\\\\"\""'
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  printf_expected = 'echo\\ "I\ said\ "row\ row\ row\ your\ boat""'
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  expect(cmd_outer).to eql expected
         
     | 
| 
      
 51 
     | 
    
         
            +
                  expect(%x{printf #{cmd_outer}}.strip).to eql printf_expected
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              context "#escape" do
         
     | 
| 
      
 56 
     | 
    
         
            +
                it "escapes strings with quotes" do
         
     | 
| 
      
 57 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new '"hi"'
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  expected = '\"hi\"'
         
     | 
| 
      
 60 
     | 
    
         
            +
                  expect(cmd.escape_cmd).to eql expected
         
     | 
| 
      
 61 
     | 
    
         
            +
                  expect(%x{printf #{expected}}.strip).to eql unescape_cmd(cmd)
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                it "ignores strings without quotes" do
         
     | 
| 
      
 65 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new 'hi'
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  expected = 'hi'
         
     | 
| 
      
 68 
     | 
    
         
            +
                  expect(cmd.escape_cmd).to eql expected
         
     | 
| 
      
 69 
     | 
    
         
            +
                  expect(%x{printf #{expected}}.strip).to eql unescape_cmd(cmd)
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                it "escapes nested quotes" do
         
     | 
| 
      
 73 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new 'echo "hi"'
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  expected = 'echo\\ \"hi\"'
         
     | 
| 
      
 76 
     | 
    
         
            +
                  expect(cmd.escape_cmd).to eql expected
         
     | 
| 
      
 77 
     | 
    
         
            +
                  expect(%x{printf #{expected}}.strip).to eql unescape_cmd(cmd)
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                it "respects frozen? string" do
         
     | 
| 
      
 81 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new :echo, "\"^FROZEN^\"".freeze, :"^", "^"
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  expected = 'echo "^FROZEN^" ^ \^'
         
     | 
| 
      
 84 
     | 
    
         
            +
                  expect(cmd.escape_cmd).to eql expected
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                it "respects wrapped frozen? strings" do
         
     | 
| 
      
 88 
     | 
    
         
            +
                  cmd_inner = Loom::Shell::CmdWrapper.new :echo, "\"^#FROZEN^\"".freeze
         
     | 
| 
      
 89 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.wrap_cmd :sudo, cmd_inner
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  expected = 'sudo echo "^#FROZEN^"'
         
     | 
| 
      
 92 
     | 
    
         
            +
                  expect(cmd.escape_cmd).to eql expected
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
              # I don't want to think about this shit anymore. Don't touch this unless its
         
     | 
| 
      
 97 
     | 
    
         
            +
              # broken.
         
     | 
| 
      
 98 
     | 
    
         
            +
              context "#wrap" do
         
     | 
| 
      
 99 
     | 
    
         
            +
                it "preserves escaped CmdWrappers: depth 2" do
         
     | 
| 
      
 100 
     | 
    
         
            +
                  cmd_which = Loom::Shell::CmdWrapper.new :which, :ls
         
     | 
| 
      
 101 
     | 
    
         
            +
                  cmd_sh = Loom::Shell::CmdWrapper.new :"/bin/sh", "-c", should_quote: true
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                  composed_cmd = cmd_sh.wrap(cmd_sh.wrap(cmd_which)).to_s
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                  expected = "/bin/sh -c \"/bin/sh -c \\\"which ls\\\"\""
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                  expect(composed_cmd).to eql expected
         
     | 
| 
      
 108 
     | 
    
         
            +
                  # Matches /bin/ls$ for portability, on fedora it's /usr/bin/ls
         
     | 
| 
      
 109 
     | 
    
         
            +
                  expect(%x{#{composed_cmd}}.strip).to match /\/bin\/ls$/
         
     | 
| 
      
 110 
     | 
    
         
            +
                end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                it "preserves escaped CmdWrappers: depth N" do
         
     | 
| 
      
 113 
     | 
    
         
            +
                  cmd_which = Loom::Shell::CmdWrapper.new :which, :ls
         
     | 
| 
      
 114 
     | 
    
         
            +
                  cmd_sh = Loom::Shell::CmdWrapper.new :"/bin/sh", "-c", should_quote: true
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                  composed_cmd = cmd_sh.wrap(cmd_sh.wrap(cmd_sh.wrap(cmd_which))).to_s
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                  expected =
         
     | 
| 
      
 119 
     | 
    
         
            +
                    "/bin/sh -c \"/bin/sh -c \\\"/bin/sh -c \\\\\\\"which ls\\\\\\\"\\\"\""
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                  expect(composed_cmd).to eql expected
         
     | 
| 
      
 122 
     | 
    
         
            +
                  # Matches /bin/ls$ for portability, on fedora it's /usr/bin/ls
         
     | 
| 
      
 123 
     | 
    
         
            +
                  expect(%x{#{composed_cmd}}.strip).to match /\/bin\/ls$/
         
     | 
| 
      
 124 
     | 
    
         
            +
                end
         
     | 
| 
      
 125 
     | 
    
         
            +
              end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
              context Loom::Shell::CmdRedirect do
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                let(:cmd_parts) { [:"/bin/ls"] }
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                it "redirects stdout to file" do
         
     | 
| 
      
 132 
     | 
    
         
            +
                  redirect = Loom::Shell::CmdRedirect.new "/my/file"
         
     | 
| 
      
 133 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new *cmd_parts, redirect: redirect
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                  expect(cmd.to_s).to eql "/bin/ls >/my/file"
         
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                it "redirects stderr to file" do
         
     | 
| 
      
 139 
     | 
    
         
            +
                  redirect = Loom::Shell::CmdRedirect.new "/my/file", fd: 2
         
     | 
| 
      
 140 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new *cmd_parts, redirect: redirect
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                  expect(cmd.to_s).to eql "/bin/ls 2>/my/file"
         
     | 
| 
      
 143 
     | 
    
         
            +
                end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                it "appends stdout to file" do
         
     | 
| 
      
 146 
     | 
    
         
            +
                  mode = Loom::Shell::CmdRedirect::Mode::APPEND
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                  redirect = Loom::Shell::CmdRedirect.new "/my/file", mode: mode
         
     | 
| 
      
 149 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new *cmd_parts, redirect: redirect
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                  expect(cmd.to_s).to eql "/bin/ls >>/my/file"
         
     | 
| 
      
 152 
     | 
    
         
            +
                end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                it "appends stderr to file" do
         
     | 
| 
      
 155 
     | 
    
         
            +
                  mode = Loom::Shell::CmdRedirect::Mode::APPEND
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                  redirect = Loom::Shell::CmdRedirect.new "/my/file", fd: 2, mode: mode
         
     | 
| 
      
 158 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new *cmd_parts, redirect: redirect
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                  expect(cmd.to_s).to eql "/bin/ls 2>>/my/file"
         
     | 
| 
      
 161 
     | 
    
         
            +
                end
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                it "redirects stderr to stdout" do
         
     | 
| 
      
 164 
     | 
    
         
            +
                  redirect = Loom::Shell::CmdRedirect.new 1, fd: 2
         
     | 
| 
      
 165 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new *cmd_parts, redirect: redirect
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                  expect(cmd.to_s).to eql "/bin/ls 2>1"
         
     | 
| 
      
 168 
     | 
    
         
            +
                end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                it "redirects both stderr and stdout to file" do
         
     | 
| 
      
 171 
     | 
    
         
            +
                  mode = Loom::Shell::CmdRedirect::Mode::OUTPUT_12
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                  redirect = Loom::Shell::CmdRedirect.new "/my/file", mode: mode
         
     | 
| 
      
 174 
     | 
    
         
            +
                  cmd = Loom::Shell::CmdWrapper.new *cmd_parts, redirect: redirect
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                  expect(cmd.to_s).to eql "/bin/ls &>/my/file"
         
     | 
| 
      
 177 
     | 
    
         
            +
                end
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                context "helper factories" do
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
                  it "appends to stdout" do
         
     | 
| 
      
 182 
     | 
    
         
            +
                    redirect = Loom::Shell::CmdRedirect.append_stdout "/my/file"
         
     | 
| 
      
 183 
     | 
    
         
            +
                    cmd = Loom::Shell::CmdWrapper.new *cmd_parts, redirect: redirect
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                    expect(cmd.to_s).to eql "/bin/ls >>/my/file"
         
     | 
| 
      
 186 
     | 
    
         
            +
                  end
         
     | 
| 
      
 187 
     | 
    
         
            +
                end
         
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
                context "multiple redirects" do
         
     | 
| 
      
 190 
     | 
    
         
            +
                  it "redirects both stderr and stdout to file" do
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                    redirects = [
         
     | 
| 
      
 193 
     | 
    
         
            +
                      Loom::Shell::CmdRedirect.new("/my/file"),
         
     | 
| 
      
 194 
     | 
    
         
            +
                      Loom::Shell::CmdRedirect.new(1, fd: 2)
         
     | 
| 
      
 195 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 196 
     | 
    
         
            +
                    cmd = Loom::Shell::CmdWrapper.new *cmd_parts, redirect: redirects
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
                    expect(cmd.to_s).to eql "/bin/ls >/my/file 2>1"
         
     | 
| 
      
 199 
     | 
    
         
            +
                  end
         
     | 
| 
      
 200 
     | 
    
         
            +
                end
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
                context "wrapped redirects" do
         
     | 
| 
      
 203 
     | 
    
         
            +
                  it "does not escape redirects" do
         
     | 
| 
      
 204 
     | 
    
         
            +
                    skip "fails - this is why I started implementing the harness see " +
         
     | 
| 
      
 205 
     | 
    
         
            +
                      "`git show 1196d2ec2` for info"
         
     | 
| 
      
 206 
     | 
    
         
            +
                    r = Loom::Shell::CmdRedirect.append_stdout "/my/file"
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
                    cmd_inner = Loom::Shell::CmdWrapper.new :echo, :hello, redirect: r
         
     | 
| 
      
 209 
     | 
    
         
            +
                    cmd = Loom::Shell::CmdWrapper.wrap_cmd :sudo, "-u", :root, cmd_inner
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
                    expect(cmd.to_s).to eql "sudo -u root echo hello >>/my/file"
         
     | 
| 
      
 212 
     | 
    
         
            +
                  end
         
     | 
| 
      
 213 
     | 
    
         
            +
                end
         
     | 
| 
      
 214 
     | 
    
         
            +
              end
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
              context Loom::Shell::CmdPipeline do
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
                let(:cmds) do
         
     | 
| 
      
 219 
     | 
    
         
            +
                  [
         
     | 
| 
      
 220 
     | 
    
         
            +
                    Loom::Shell::CmdWrapper.new(:find, ".", "-name", "*foo", "-print0"),
         
     | 
| 
      
 221 
     | 
    
         
            +
                    Loom::Shell::CmdWrapper.new(:xargs, "-0", "-I-", "ls", "-")
         
     | 
| 
      
 222 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 223 
     | 
    
         
            +
                end
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
                it "pipes commands together" do
         
     | 
| 
      
 226 
     | 
    
         
            +
                  pipeline = Loom::Shell::CmdPipeline.new cmds
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
                  expected = "find . -name \\*foo -print0 | xargs -0 -I- ls -"
         
     | 
| 
      
 229 
     | 
    
         
            +
                  expect(pipeline.to_s).to eql expected
         
     | 
| 
      
 230 
     | 
    
         
            +
                end
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
      
 232 
     | 
    
         
            +
                it "accepts commands as pre-escaped strings" do
         
     | 
| 
      
 233 
     | 
    
         
            +
                  pipeline = Loom::Shell::CmdPipeline.new ["I'm already escaped", "me too!"]
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
      
 235 
     | 
    
         
            +
                  expected = "I'm already escaped | me too!"
         
     | 
| 
      
 236 
     | 
    
         
            +
                  expect(pipeline.to_s).to eql expected
         
     | 
| 
      
 237 
     | 
    
         
            +
                end
         
     | 
| 
      
 238 
     | 
    
         
            +
              end
         
     | 
| 
      
 239 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            describe Loom::Shell::HarnessBlob do
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              HARNESS = "./scripts/harness.sh"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              # Set debug_script to true in a context to see STDERR debugging.
         
     | 
| 
      
 6 
     | 
    
         
            +
              let(:debug_script) { false }
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              let(:cmd) { 'echo hi there | (echo "from subshell"; cat);' }
         
     | 
| 
      
 9 
     | 
    
         
            +
              let(:encoded_script) do
         
     | 
| 
      
 10 
     | 
    
         
            +
                run_harnes_script "--print_base64", :stdin => cmd
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
              let(:golden_checksum) do
         
     | 
| 
      
 13 
     | 
    
         
            +
                run_harnes_script "--print_checksum", encoded_script
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              def run_harnes_script(cmd, *args, stdin: nil)
         
     | 
| 
      
 18 
     | 
    
         
            +
                cmd = %Q{./scripts/harness.sh 2>/dev/null #{cmd}}
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                heredoc = nil
         
     | 
| 
      
 21 
     | 
    
         
            +
                if stdin
         
     | 
| 
      
 22 
     | 
    
         
            +
                  heredoc = "<<'EOS'\n#{stdin}\nEOS"
         
     | 
| 
      
 23 
     | 
    
         
            +
                  cmd << " - #{args.join " "} #{heredoc}"
         
     | 
| 
      
 24 
     | 
    
         
            +
                else
         
     | 
| 
      
 25 
     | 
    
         
            +
                  cmd << " #{args.join " "}"
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                %x{#{cmd}}
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              describe "scripts/harness.sh parity" do
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                subject { Loom::Shell::HarnessBlob.new cmd }
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                it "computes a valid script checksum" do
         
     | 
| 
      
 36 
     | 
    
         
            +
                  run_harnes_script "--check", golden_checksum, {
         
     | 
| 
      
 37 
     | 
    
         
            +
                                      :stdin => subject.encoded_script
         
     | 
| 
      
 38 
     | 
    
         
            +
                                    }
         
     | 
| 
      
 39 
     | 
    
         
            +
                  expect($?.exitstatus).to eq 0
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
            end
         
     |