wavefront-cli 2.12.0 → 2.13.0
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 +4 -4
- data/HISTORY.md +8 -0
- data/lib/wavefront-cli/alert.rb +6 -0
- data/lib/wavefront-cli/commands/alert.rb +6 -4
- data/lib/wavefront-cli/commands/dashboard.rb +2 -0
- data/lib/wavefront-cli/commands/query.rb +10 -4
- data/lib/wavefront-cli/dashboard.rb +31 -0
- data/lib/wavefront-cli/display/alert.rb +8 -0
- data/lib/wavefront-cli/display/base.rb +8 -0
- data/lib/wavefront-cli/display/dashboard.rb +9 -0
- data/lib/wavefront-cli/display/printer/terse.rb +1 -0
- data/lib/wavefront-cli/output/csv.rb +8 -0
- data/lib/wavefront-cli/output/csv/base.rb +18 -0
- data/lib/wavefront-cli/output/csv/query.rb +117 -0
- data/lib/wavefront-cli/version.rb +1 -1
- data/spec/wavefront-cli/output/csv/query_spec.rb +150 -0
- data/spec/wavefront-cli/output/csv_spec.rb +43 -0
- metadata +9 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: c9007cbf188f6962a31b04002c5b64c86e85bbc2ddad05e5299647706970ad65
         | 
| 4 | 
            +
              data.tar.gz: 6b5daf8e04b6d5090837620f51dc9e1b5ce3c9d45227fe66d118a2adb94e758b
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: c224961d3690bed9d069d689d632c726262342ad4cc278b1942d4e70cc54a4263e0d89eda027b156cd93fde9184db04f831f75cbad3fe374f5a45f3eb7f30769
         | 
| 7 | 
            +
              data.tar.gz: 2b20581ec22ae10242eea44ff07862b43eeb5bac057774b56aa6f3a363379298dbaca416859d1c274770edb376fe4bf3f85484876e16db23a475c457b850ac1b
         | 
    
        data/HISTORY.md
    CHANGED
    
    | @@ -1,5 +1,13 @@ | |
| 1 1 | 
             
            # Changelog
         | 
| 2 2 |  | 
| 3 | 
            +
            ## 2.13.0 (11/12/2018)
         | 
| 4 | 
            +
            * Add CSV output for `query` command.
         | 
| 5 | 
            +
            * Add multiple format outputs for all applicable `alert`
         | 
| 6 | 
            +
              subcommands.
         | 
| 7 | 
            +
            * Add `queries` subcommand for `alert` and `dashboard` subcommands,
         | 
| 8 | 
            +
              to quickly see which queries (and therefore timeseries) are being
         | 
| 9 | 
            +
              used.
         | 
| 10 | 
            +
             | 
| 3 11 | 
             
            ## 2.12.0 (26/11/2018)
         | 
| 4 12 | 
             
            * Support SDK's new `unix` writer, which lets you write points to a
         | 
| 5 13 | 
             
              local Unix datagram socket. This requires `-u unix` and `-S
         | 
    
        data/lib/wavefront-cli/alert.rb
    CHANGED
    
    | @@ -54,6 +54,12 @@ module WavefrontCli | |
| 54 54 | 
             
                  in_state(:firing)
         | 
| 55 55 | 
             
                end
         | 
| 56 56 |  | 
| 57 | 
            +
                def do_queries
         | 
| 58 | 
            +
                  wf.list(0, :all).tap do |r|
         | 
| 59 | 
            +
                    r.response.items.map! { |a| { id: a.id, condition: a.condition } }
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 57 63 | 
             
                # How many alerts are in the given state? If none, say so,
         | 
| 58 64 | 
             
                # rather than just printing nothing.
         | 
| 59 65 | 
             
                #
         | 
| @@ -9,8 +9,8 @@ class WavefrontCommandAlert < WavefrontCommandBase | |
| 9 9 |  | 
| 10 10 | 
             
              def _commands
         | 
| 11 11 | 
             
                ["list #{CMN} [-al] [-f format] [-o offset] [-L limit]",
         | 
| 12 | 
            -
                 "firing #{CMN} [-o offset] [-L limit]",
         | 
| 13 | 
            -
                 "snoozed #{CMN} [-o offset] [-L limit]",
         | 
| 12 | 
            +
                 "firing #{CMN} [-f format] [-o offset] [-L limit]",
         | 
| 13 | 
            +
                 "snoozed #{CMN} [-f format] [-o offset] [-L limit]",
         | 
| 14 14 | 
             
                 "describe #{CMN} [-f format] [-v version] <id>",
         | 
| 15 15 | 
             
                 "delete #{CMN} <id>",
         | 
| 16 16 | 
             
                 "undelete #{CMN} <id>",
         | 
| @@ -25,8 +25,9 @@ class WavefrontCommandAlert < WavefrontCommandBase | |
| 25 25 | 
             
                 "tag clear #{CMN} <id>",
         | 
| 26 26 | 
             
                 "tag add #{CMN} <id> <tag>",
         | 
| 27 27 | 
             
                 "tag delete #{CMN} <id> <tag>",
         | 
| 28 | 
            -
                 "currently #{CMN} <state>",
         | 
| 29 | 
            -
                 " | 
| 28 | 
            +
                 "currently #{CMN} [-f format] <state>",
         | 
| 29 | 
            +
                 "queries #{CMN} [-f format] [-b]",
         | 
| 30 | 
            +
                 "summary #{CMN} [-f format] [-a]"]
         | 
| 30 31 | 
             
              end
         | 
| 31 32 |  | 
| 32 33 | 
             
              def _options
         | 
| @@ -37,6 +38,7 @@ class WavefrontCommandAlert < WavefrontCommandBase | |
| 37 38 | 
             
                 '-o, --offset=n           start from nth alert',
         | 
| 38 39 | 
             
                 '-L, --limit=COUNT        number of alerts to list',
         | 
| 39 40 | 
             
                 '-T, --time=SECONDS       how long to snooze (default 3600)',
         | 
| 41 | 
            +
                 '-b, --brief              do not show alert names',
         | 
| 40 42 | 
             
                 '-f, --format=STRING      output format']
         | 
| 41 43 | 
             
              end
         | 
| 42 44 | 
             
            end
         | 
| @@ -16,6 +16,7 @@ class WavefrontCommandDashboard < WavefrontCommandBase | |
| 16 16 | 
             
                 "undelete #{CMN} <id>",
         | 
| 17 17 | 
             
                 "history #{CMN} [-f format] [-o offset] [-L limit] <id>",
         | 
| 18 18 | 
             
                 "search #{CMN} [-al] [-f format] [-o offset] [-L limit] <condition>...",
         | 
| 19 | 
            +
                 "queries #{CMN} [-f format] [-b]",
         | 
| 19 20 | 
             
                 tag_commands]
         | 
| 20 21 | 
             
              end
         | 
| 21 22 |  | 
| @@ -26,6 +27,7 @@ class WavefrontCommandDashboard < WavefrontCommandBase | |
| 26 27 | 
             
                 '-o, --offset=n           start list from nth dashboard or revision',
         | 
| 27 28 | 
             
                 '-L, --limit=COUNT        number of dashboards or revisions to list',
         | 
| 28 29 | 
             
                 '-v, --version=INTEGER    version of dashboard',
         | 
| 30 | 
            +
                 '-b, --brief              do not show dashboard names',
         | 
| 29 31 | 
             
                 '-f, --format=STRING      output format']
         | 
| 30 32 | 
             
              end
         | 
| 31 33 | 
             
            end
         | 
| @@ -10,10 +10,11 @@ class WavefrontCommandQuery < WavefrontCommandBase | |
| 10 10 | 
             
              def _commands
         | 
| 11 11 | 
             
                ['aliases [-DV] [-c file] [-P profile]',
         | 
| 12 12 | 
             
                 "#{CMN} [-g granularity] [-s time] [-e time] [-f format] " \
         | 
| 13 | 
            -
                       '[-WikvO] [-S mode] [-N name] [-p points] <query>',
         | 
| 14 | 
            -
                 "raw #{CMN} [-H host] [-s time] [-e time] [-f format]  | 
| 13 | 
            +
                       '[-WikvO] [-S mode] [-N name] [-p points] [-F options] <query>',
         | 
| 14 | 
            +
                 "raw #{CMN} [-H host] [-s time] [-e time] [-f format] " \
         | 
| 15 | 
            +
                       '[-F options] <metric>',
         | 
| 15 16 | 
             
                 "run #{CMN} [-g granularity] [-s time] [-e time] [-f format] " \
         | 
| 16 | 
            -
                       '[-WkivO] [-S mode] [-N name] [-p points] <alias>']
         | 
| 17 | 
            +
                       '[-F options] [-WkivO] [-S mode] [-N name] [-p points] <alias>']
         | 
| 17 18 | 
             
              end
         | 
| 18 19 |  | 
| 19 20 | 
             
              def _options
         | 
| @@ -31,6 +32,8 @@ class WavefrontCommandQuery < WavefrontCommandBase | |
| 31 32 | 
             
                 '-O, --obsolete            include metrics unreported for > 4 weeks',
         | 
| 32 33 | 
             
                 '-H, --host=STRING         host or source to query on',
         | 
| 33 34 | 
             
                 '-f, --format=STRING       output format',
         | 
| 35 | 
            +
                 '-F, --format-opts=STRING  comma-separated options to pass to ' \
         | 
| 36 | 
            +
                                            'output formatter',
         | 
| 34 37 | 
             
                 '-k, --nospark             do not show sparkline',
         | 
| 35 38 | 
             
                 '-W, --nowarn              do not show API warning messages']
         | 
| 36 39 | 
             
              end
         | 
| @@ -38,6 +41,9 @@ class WavefrontCommandQuery < WavefrontCommandBase | |
| 38 41 | 
             
              def postscript
         | 
| 39 42 | 
             
                'The query command has an additional output format. Using ' \
         | 
| 40 43 | 
             
                "'-f wavefront' produces output suitable for feeding back into a " \
         | 
| 41 | 
            -
                 | 
| 44 | 
            +
                "proxy. Other output formats are 'yaml', 'json', 'ruby', "\
         | 
| 45 | 
            +
                "and 'csv'. CSV format options are 'header' (print column headers); " \
         | 
| 46 | 
            +
                "'tagkeys' (print tags as key=value rather than value); and 'quote' " \
         | 
| 47 | 
            +
                '(force quoting of every CSV element).'.cmd_fold(TW, 0)
         | 
| 42 48 | 
             
              end
         | 
| 43 49 | 
             
            end
         | 
| @@ -23,5 +23,36 @@ module WavefrontCli | |
| 23 23 | 
             
                def do_history
         | 
| 24 24 | 
             
                  wf.history(options[:'<id>'])
         | 
| 25 25 | 
             
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def do_queries
         | 
| 28 | 
            +
                  resp = wf.list(0, :all)
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  queries = resp.response.items.each_with_object({}) do |d, a|
         | 
| 31 | 
            +
                    a[d.id] = extract_values(d, 'query')
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  resp.tap { |r| r.response.items = queries }
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                # @param obj [Object] the thing to search
         | 
| 38 | 
            +
                # @param key [String, Symbol] the key to search for
         | 
| 39 | 
            +
                # @param aggr [Array] values of matched keys
         | 
| 40 | 
            +
                # @return [Array]
         | 
| 41 | 
            +
                #
         | 
| 42 | 
            +
                def extract_values(obj, key, aggr = [])
         | 
| 43 | 
            +
                  if obj.is_a?(Hash)
         | 
| 44 | 
            +
                    obj.each_pair do |k, v|
         | 
| 45 | 
            +
                      if k == key && !v.to_s.empty?
         | 
| 46 | 
            +
                        aggr.<< v
         | 
| 47 | 
            +
                      else
         | 
| 48 | 
            +
                        extract_values(v, key, aggr)
         | 
| 49 | 
            +
                      end
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
                  elsif obj.is_a?(Array)
         | 
| 52 | 
            +
                    obj.each { |e| extract_values(e, key, aggr) }
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  aggr
         | 
| 56 | 
            +
                end
         | 
| 26 57 | 
             
              end
         | 
| 27 58 | 
             
            end
         | 
| @@ -55,5 +55,13 @@ module WavefrontDisplay | |
| 55 55 | 
             
                  data.sort.each { |k, v| puts format("%-#{kw}s%s", k, v) }
         | 
| 56 56 | 
             
                end
         | 
| 57 57 | 
             
                # rubocop:enable Metrics/AbcSize
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                def do_queries
         | 
| 60 | 
            +
                  if options[:brief]
         | 
| 61 | 
            +
                    multicolumn(:condition)
         | 
| 62 | 
            +
                  else
         | 
| 63 | 
            +
                    multicolumn(:id, :condition)
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
                end
         | 
| 58 66 | 
             
              end
         | 
| 59 67 | 
             
            end
         | 
| @@ -220,6 +220,14 @@ module WavefrontDisplay | |
| 220 220 | 
             
                  end
         | 
| 221 221 | 
             
                end
         | 
| 222 222 |  | 
| 223 | 
            +
                def do_queries
         | 
| 224 | 
            +
                  if options[:brief]
         | 
| 225 | 
            +
                    multicolumn(:condition)
         | 
| 226 | 
            +
                  else
         | 
| 227 | 
            +
                    multicolumn(:id, :condition)
         | 
| 228 | 
            +
                  end
         | 
| 229 | 
            +
                end
         | 
| 230 | 
            +
             | 
| 223 231 | 
             
                # Modify, in-place, the data structure to remove fields which
         | 
| 224 232 | 
             
                # we deem not of interest to the user.
         | 
| 225 233 | 
             
                #
         | 
| @@ -17,5 +17,14 @@ module WavefrontDisplay | |
| 17 17 | 
             
                  data[:sections] = data[:sections].map { |s| s[:name] }
         | 
| 18 18 | 
             
                  long_output
         | 
| 19 19 | 
             
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def do_queries
         | 
| 22 | 
            +
                  if options[:brief]
         | 
| 23 | 
            +
                    @data = data.to_h.values.flatten.map { |q| { query: q } }
         | 
| 24 | 
            +
                    multicolumn(:query)
         | 
| 25 | 
            +
                  else
         | 
| 26 | 
            +
                    long_output
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                end
         | 
| 20 29 | 
             
              end
         | 
| 21 30 | 
             
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            module WavefrontCsvOutput
         | 
| 2 | 
            +
              #
         | 
| 3 | 
            +
              # Standard output template
         | 
| 4 | 
            +
              #
         | 
| 5 | 
            +
              class Base
         | 
| 6 | 
            +
                attr_reader :resp, :options
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def initialize(resp, options)
         | 
| 9 | 
            +
                  @resp        = resp
         | 
| 10 | 
            +
                  @options     = options
         | 
| 11 | 
            +
                  post_initialize if respond_to?(:post_initialize)
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def run
         | 
| 15 | 
            +
                  puts _run
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,117 @@ | |
| 1 | 
            +
            require 'set'
         | 
| 2 | 
            +
            require_relative 'base'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module WavefrontCsvOutput
         | 
| 5 | 
            +
              #
         | 
| 6 | 
            +
              # Display query results in CSV format.
         | 
| 7 | 
            +
              #
         | 
| 8 | 
            +
              # The following options are supported:
         | 
| 9 | 
            +
              #  quote   -- puts all values in soft quotes
         | 
| 10 | 
            +
              #  headers -- print CSV column headers
         | 
| 11 | 
            +
              #  tagkeys -- normally point tag keys go in the header and values in
         | 
| 12 | 
            +
              #             the CSV data. This option puts key=value in the CSV.
         | 
| 13 | 
            +
              #
         | 
| 14 | 
            +
              class Query < Base
         | 
| 15 | 
            +
                attr_reader :columns, :formatopts, :headers, :data_map
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def _run
         | 
| 18 | 
            +
                  csv_headers + csv_body
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def post_initialize
         | 
| 22 | 
            +
                  @headers = []
         | 
| 23 | 
            +
                  @formatopts = extract_formatopts
         | 
| 24 | 
            +
                  @data_map    = options[:raw] ? raw_output : query_output
         | 
| 25 | 
            +
                  @columns     = all_keys.freeze
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                # @return [Array[Hash]] which goes in the @data_map
         | 
| 29 | 
            +
                #
         | 
| 30 | 
            +
                def raw_output
         | 
| 31 | 
            +
                  resp.each_with_object([]) do |point, a|
         | 
| 32 | 
            +
                    point[:points].each do |p|
         | 
| 33 | 
            +
                      a.<< csv_format(options[:'<metric>'],
         | 
| 34 | 
            +
                                      p[:value],
         | 
| 35 | 
            +
                                      p[:timestamp],
         | 
| 36 | 
            +
                                      options[:host],
         | 
| 37 | 
            +
                                      point[:tags])
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                # @return [Array[Hash]] which goes in the @data_map
         | 
| 43 | 
            +
                #
         | 
| 44 | 
            +
                def query_output
         | 
| 45 | 
            +
                  resp[:timeseries].each_with_object([]) do |ts, a|
         | 
| 46 | 
            +
                    ts[:data].each do |point|
         | 
| 47 | 
            +
                      a.<< csv_format(ts[:label],
         | 
| 48 | 
            +
                                      point[1],
         | 
| 49 | 
            +
                                      point[0],
         | 
| 50 | 
            +
                                      ts[:host],
         | 
| 51 | 
            +
                                      ts[:tags])
         | 
| 52 | 
            +
                    end
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                # @return [Array] unique list of all keys in an array of hashes
         | 
| 57 | 
            +
                #
         | 
| 58 | 
            +
                def all_keys(data = data_map)
         | 
| 59 | 
            +
                  data.each_with_object(Set.new) { |row, a| a.merge(row.keys) }.to_a
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                # @return [Array] single element of comma-separated CSV column
         | 
| 63 | 
            +
                #   headers if requested, otherwise []
         | 
| 64 | 
            +
                #
         | 
| 65 | 
            +
                def csv_headers
         | 
| 66 | 
            +
                  return [] unless formatopts.include?('headers')
         | 
| 67 | 
            +
                  [columns.map { |c| csv_value(c) }.join(',')]
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                def csv_body
         | 
| 71 | 
            +
                  data_map.map { |r| map_row_to_csv(r) }
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                def map_row_to_csv(row)
         | 
| 75 | 
            +
                  columns.map { |col| csv_value(row[col]) }.join(',')
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                # Do escaping and quoting
         | 
| 79 | 
            +
                #
         | 
| 80 | 
            +
                def csv_value(value)
         | 
| 81 | 
            +
                  if (formatopts.include?('quote') || value =~ /[,\s"]/) &&
         | 
| 82 | 
            +
                     !value.to_s.empty?
         | 
| 83 | 
            +
                    quote_value(value)
         | 
| 84 | 
            +
                  else
         | 
| 85 | 
            +
                    value
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                def quote_value(value)
         | 
| 90 | 
            +
                  format('"%s"', value.to_s.gsub(/"/, '\"'))
         | 
| 91 | 
            +
                end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                # Turn a string of output options into an easy-to-query array
         | 
| 94 | 
            +
                #
         | 
| 95 | 
            +
                def extract_formatopts
         | 
| 96 | 
            +
                  options[:formatopts].nil? ? [] : options[:formatopts].split(',')
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                # Take the data describing a point, and turn it into a CSV row.
         | 
| 100 | 
            +
                # Tags have their keys removed.
         | 
| 101 | 
            +
                #
         | 
| 102 | 
            +
                def csv_format(path, value, timestamp, source, tags = nil)
         | 
| 103 | 
            +
                  ret = { path:      path,
         | 
| 104 | 
            +
                          value:     value,
         | 
| 105 | 
            +
                          timestamp: timestamp,
         | 
| 106 | 
            +
                          source:    source }
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                  ret.tap { |r| tags.each { |k, v| r[k.to_sym] = tag_val(k, v) } }
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                # We may be doing key=val or just val, depending on the formatter options
         | 
| 112 | 
            +
                #
         | 
| 113 | 
            +
                def tag_val(key, val)
         | 
| 114 | 
            +
                  formatopts.include?('tagkeys') ? format('%s=%s', key, val) : val
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
              end
         | 
| 117 | 
            +
            end
         | 
| @@ -1 +1 @@ | |
| 1 | 
            -
            WF_CLI_VERSION = '2. | 
| 1 | 
            +
            WF_CLI_VERSION = '2.13.0'.freeze
         | 
| @@ -0,0 +1,150 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative '../../../spec_helper'
         | 
| 4 | 
            +
            require_relative '../../../../lib/wavefront-cli/output/csv/query'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            # Test CSV output
         | 
| 7 | 
            +
            #
         | 
| 8 | 
            +
            class WavefrontOutputCsvTest < MiniTest::Test
         | 
| 9 | 
            +
              attr_reader :wfq, :wfr, :wfqq, :wfh, :wft
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def setup
         | 
| 12 | 
            +
                @wfq = WavefrontCsvOutput::Query.new(load_query_response, {})
         | 
| 13 | 
            +
                @wfr = WavefrontCsvOutput::Query.new(
         | 
| 14 | 
            +
                  load_raw_query_response,
         | 
| 15 | 
            +
                  raw: true,
         | 
| 16 | 
            +
                  host: 'www-blue',
         | 
| 17 | 
            +
                  '<metric>': 'solaris.network.obytes64'
         | 
| 18 | 
            +
                )
         | 
| 19 | 
            +
                @wfqq = WavefrontCsvOutput::Query.new(load_query_response,
         | 
| 20 | 
            +
                                                      formatopts: 'quote')
         | 
| 21 | 
            +
                @wfh = WavefrontCsvOutput::Query.new(load_query_response,
         | 
| 22 | 
            +
                                                     formatopts: 'headers')
         | 
| 23 | 
            +
                @wft = WavefrontCsvOutput::Query.new(load_query_response,
         | 
| 24 | 
            +
                                                     formatopts: 'tagkeys')
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              def test_all_keys
         | 
| 28 | 
            +
                assert_equal(%i[a b c d e],
         | 
| 29 | 
            +
                             wfq.all_keys([{ a: 1, b: 2 }, { a: 3, c: 3 },
         | 
| 30 | 
            +
                                           { d: 4, e: 5 }, { a: 1 }]))
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              def test_csv_value
         | 
| 34 | 
            +
                assert_equal('word', wfq.csv_value('word'))
         | 
| 35 | 
            +
                assert_equal('"word"', wfqq.csv_value('word'))
         | 
| 36 | 
            +
                assert_equal('"7\" single"', wfq.quote_value('7" single'))
         | 
| 37 | 
            +
                assert_equal('"7\" single"', wfqq.quote_value('7" single'))
         | 
| 38 | 
            +
                assert_equal('"two words"', wfq.quote_value('two words'))
         | 
| 39 | 
            +
                assert_equal('"two words"', wfqq.quote_value('two words'))
         | 
| 40 | 
            +
                assert_equal('"a, b"', wfq.quote_value('a, b'))
         | 
| 41 | 
            +
                assert_equal('"a, b"', wfqq.quote_value('a, b'))
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              def test_quote_value
         | 
| 45 | 
            +
                assert_equal('"word"', wfq.quote_value('word'))
         | 
| 46 | 
            +
                assert_equal('"1"', wfr.quote_value(1))
         | 
| 47 | 
            +
                assert_equal('"two words"', wft.quote_value('two words'))
         | 
| 48 | 
            +
                assert_equal('"7\" single"', wfh.quote_value('7" single'))
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              def test_csv_headers
         | 
| 52 | 
            +
                assert_empty(wfq.csv_headers)
         | 
| 53 | 
            +
                wfh = WavefrontCsvOutput::Query.new(load_query_response,
         | 
| 54 | 
            +
                                                    formatopts: 'headers')
         | 
| 55 | 
            +
                assert_equal(['path,value,timestamp,source,colour,environment,' \
         | 
| 56 | 
            +
                              'product,role,nic,platform,dc'], wfh.csv_headers)
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              def test_map_row_to_csv
         | 
| 60 | 
            +
                assert_equal(',,,,,,,,,,', wfq.map_row_to_csv(merp: 1))
         | 
| 61 | 
            +
                assert_equal('test.path,1,1544529523,testsource,,"unit test",,,,,',
         | 
| 62 | 
            +
                             wfq.map_row_to_csv(path:        'test.path',
         | 
| 63 | 
            +
                                                value:       1,
         | 
| 64 | 
            +
                                                timestamp:   1_544_529_523,
         | 
| 65 | 
            +
                                                source:      'testsource',
         | 
| 66 | 
            +
                                                environment: 'unit test'))
         | 
| 67 | 
            +
                assert_equal('"test.path","1","1544529523","testsource",,"unit test",,,,,',
         | 
| 68 | 
            +
                             wfqq.map_row_to_csv(path:        'test.path',
         | 
| 69 | 
            +
                                                 value:       1,
         | 
| 70 | 
            +
                                                 timestamp:   1_544_529_523,
         | 
| 71 | 
            +
                                                 source:      'testsource',
         | 
| 72 | 
            +
                                                 environment: 'unit test'))
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              def test_csv_format
         | 
| 76 | 
            +
                assert_equal({ path:        'test.path',
         | 
| 77 | 
            +
                               value:       1,
         | 
| 78 | 
            +
                               timestamp:   1_544_529_523,
         | 
| 79 | 
            +
                               source:      'testsource',
         | 
| 80 | 
            +
                               environment: 'test',
         | 
| 81 | 
            +
                               dc:          'travis' },
         | 
| 82 | 
            +
                             wfq.csv_format('test.path', 1, 1_544_529_523, 'testsource',
         | 
| 83 | 
            +
                                            environment: 'test', dc: 'travis'))
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                assert_equal({ path:        'test.path',
         | 
| 86 | 
            +
                               value:       1,
         | 
| 87 | 
            +
                               timestamp:   1_544_529_523,
         | 
| 88 | 
            +
                               source:      'testsource',
         | 
| 89 | 
            +
                               environment: 'environment=test',
         | 
| 90 | 
            +
                               dc:          'dc=travis' },
         | 
| 91 | 
            +
                             wft.csv_format('test.path', 1, 1_544_529_523, 'testsource',
         | 
| 92 | 
            +
                                            environment: 'test', dc: 'travis'))
         | 
| 93 | 
            +
              end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
              def test_tag_val
         | 
| 96 | 
            +
                assert_equal('value', wfq.tag_val('key', 'value'))
         | 
| 97 | 
            +
                assert_equal('value', wfr.tag_val('key', 'value'))
         | 
| 98 | 
            +
                assert_equal('key=value', wft.tag_val('key', 'value'))
         | 
| 99 | 
            +
                assert_equal('key=value', wft.tag_val(:key, :value))
         | 
| 100 | 
            +
              end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
              def test__run_query
         | 
| 103 | 
            +
                out_q = wfq._run
         | 
| 104 | 
            +
                assert_equal(
         | 
| 105 | 
            +
                  'solaris.network.obytes64,20910.38968253968,1533679200,' \
         | 
| 106 | 
            +
                  'wavefront-blue,blue,production,websites,wavefront-proxy,net0,' \
         | 
| 107 | 
            +
                  'JPC-triton,eu-ams-1', out_q.first
         | 
| 108 | 
            +
                )
         | 
| 109 | 
            +
                assert_equal(24, out_q.size)
         | 
| 110 | 
            +
                check_csv_output(out_q)
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                out_h = wfh._run
         | 
| 113 | 
            +
                assert_equal(
         | 
| 114 | 
            +
                  'path,value,timestamp,source,colour,environment,product,role,' \
         | 
| 115 | 
            +
                  'nic,platform,dc', out_h.first
         | 
| 116 | 
            +
                )
         | 
| 117 | 
            +
                assert_equal(
         | 
| 118 | 
            +
                  'solaris.network.obytes64,20910.38968253968,1533679200,' \
         | 
| 119 | 
            +
                  'wavefront-blue,blue,production,websites,wavefront-proxy,net0,' \
         | 
| 120 | 
            +
                  'JPC-triton,eu-ams-1', out_h[1]
         | 
| 121 | 
            +
                )
         | 
| 122 | 
            +
                assert_equal(25, out_h.size)
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                out_t = wft._run
         | 
| 125 | 
            +
                assert_equal(
         | 
| 126 | 
            +
                  'solaris.network.obytes64,20910.38968253968,1533679200,' \
         | 
| 127 | 
            +
                  'wavefront-blue,colour=blue,environment=production,product=websites,' \
         | 
| 128 | 
            +
                  'role=wavefront-proxy,nic=net0,' \
         | 
| 129 | 
            +
                  'platform=JPC-triton,dc=eu-ams-1', out_t.first
         | 
| 130 | 
            +
                )
         | 
| 131 | 
            +
                assert_equal(24, out_t.size)
         | 
| 132 | 
            +
                check_csv_output(out_q)
         | 
| 133 | 
            +
              end
         | 
| 134 | 
            +
             | 
| 135 | 
            +
              def test__run_raw
         | 
| 136 | 
            +
                check_csv_output(wfq._run)
         | 
| 137 | 
            +
              end
         | 
| 138 | 
            +
             | 
| 139 | 
            +
              def check_csv_output(out)
         | 
| 140 | 
            +
                out.each do |l|
         | 
| 141 | 
            +
                  c = l.split(',', 5)
         | 
| 142 | 
            +
                  assert_equal(c[0], 'solaris.network.obytes64')
         | 
| 143 | 
            +
                  assert_match(/^[\d\.]+$/, c[1])
         | 
| 144 | 
            +
                  # query returns epoch s timestamp, raw returns epoch ms
         | 
| 145 | 
            +
                  assert_match(/^\d+$/, c[2])
         | 
| 146 | 
            +
                  assert(c[2].size == 10 || c[2].size == 13)
         | 
| 147 | 
            +
                  assert(c[3] =~ /.*blue$/)
         | 
| 148 | 
            +
                end
         | 
| 149 | 
            +
              end
         | 
| 150 | 
            +
            end
         | 
| @@ -0,0 +1,43 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative '../../spec_helper'
         | 
| 4 | 
            +
            require_relative '../../../lib/wavefront-cli/output/csv'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            # Test the CSV instantiation of the base class
         | 
| 7 | 
            +
            #
         | 
| 8 | 
            +
            class CsvOutputBaseTest < MiniTest::Test
         | 
| 9 | 
            +
              attr_reader :wfo
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def setup
         | 
| 12 | 
            +
                @wfo = WavefrontOutput::Csv.new(load_query_response, class: 'query')
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              def test_my_format
         | 
| 16 | 
            +
                assert('csv', wfo.my_format)
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              def test_command_class_name
         | 
| 20 | 
            +
                assert_equal('WavefrontCsvOutput::Query', wfo.command_class_name)
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              def test_command_file
         | 
| 24 | 
            +
                assert_equal('csv/query', wfo.command_file)
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              def test_command_class
         | 
| 28 | 
            +
                supported_commands = %w[query]
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                supported_commands.each do |cmd|
         | 
| 31 | 
            +
                  wfo = WavefrontOutput::Csv.new(load_query_response, class: cmd)
         | 
| 32 | 
            +
                  klass = wfo.command_class
         | 
| 33 | 
            +
                  assert_equal("WavefrontCsvOutput::#{cmd.capitalize}",
         | 
| 34 | 
            +
                               klass.class.name)
         | 
| 35 | 
            +
                  assert klass.respond_to?(:run)
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                (CMDS - supported_commands).each do |cmd|
         | 
| 39 | 
            +
                  wfo = WavefrontOutput::Csv.new(load_query_response, class: cmd)
         | 
| 40 | 
            +
                  assert_raises(LoadError) { wfo.command_class }
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: wavefront-cli
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 4 | 
            +
              version: 2.13.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Robert Fisher
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2018-12- | 
| 11 | 
            +
            date: 2018-12-12 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: docopt
         | 
| @@ -230,6 +230,9 @@ files: | |
| 230 230 | 
             
            - lib/wavefront-cli/notificant.rb
         | 
| 231 231 | 
             
            - lib/wavefront-cli/opt_handler.rb
         | 
| 232 232 | 
             
            - lib/wavefront-cli/output/base.rb
         | 
| 233 | 
            +
            - lib/wavefront-cli/output/csv.rb
         | 
| 234 | 
            +
            - lib/wavefront-cli/output/csv/base.rb
         | 
| 235 | 
            +
            - lib/wavefront-cli/output/csv/query.rb
         | 
| 233 236 | 
             
            - lib/wavefront-cli/output/hcl.rb
         | 
| 234 237 | 
             
            - lib/wavefront-cli/output/hcl/alert.rb
         | 
| 235 238 | 
             
            - lib/wavefront-cli/output/hcl/base.rb
         | 
| @@ -288,6 +291,8 @@ files: | |
| 288 291 | 
             
            - spec/wavefront-cli/message_spec.rb
         | 
| 289 292 | 
             
            - spec/wavefront-cli/metric_spec.rb
         | 
| 290 293 | 
             
            - spec/wavefront-cli/opt_handler_spec.rb
         | 
| 294 | 
            +
            - spec/wavefront-cli/output/csv/query_spec.rb
         | 
| 295 | 
            +
            - spec/wavefront-cli/output/csv_spec.rb
         | 
| 291 296 | 
             
            - spec/wavefront-cli/output/hcl_spec.rb
         | 
| 292 297 | 
             
            - spec/wavefront-cli/output/json_spec.rb
         | 
| 293 298 | 
             
            - spec/wavefront-cli/output/ruby_spec.rb
         | 
| @@ -366,6 +371,8 @@ test_files: | |
| 366 371 | 
             
            - spec/wavefront-cli/message_spec.rb
         | 
| 367 372 | 
             
            - spec/wavefront-cli/metric_spec.rb
         | 
| 368 373 | 
             
            - spec/wavefront-cli/opt_handler_spec.rb
         | 
| 374 | 
            +
            - spec/wavefront-cli/output/csv/query_spec.rb
         | 
| 375 | 
            +
            - spec/wavefront-cli/output/csv_spec.rb
         | 
| 369 376 | 
             
            - spec/wavefront-cli/output/hcl_spec.rb
         | 
| 370 377 | 
             
            - spec/wavefront-cli/output/json_spec.rb
         | 
| 371 378 | 
             
            - spec/wavefront-cli/output/ruby_spec.rb
         |