require 'spec_helper' require 'flydata/api/data_entry' module Flydata module Api describe DataEntry do let(:subject_object) { described_class.new(api_client) } let(:api_client) { double('api_client') } let(:data_entry_id) { 1234 } let(:options) { { tables: tables } } describe '#create' do subject { subject_object.create(params) } let(:params) { {data_port_id: 1, log_path: 'log-path'} } it 'creates data entry' do expect(api_client).to receive(:post) subject end end def build_result(complete, state, proxy_size, proxy_length, redshift_size, redshift_length, sync_redshift_size, sync_redshift_length, copy_num, query_num, message) buffer = nil queue = nil if sync_redshift_size buffer = { "proxy" => { "buffer_size" => proxy_size, "queue_length" => proxy_length, }, "redshift" => { "buffer_size" => redshift_size, "queue_length" => redshift_length, }, "sync_redshift" => { "buffer_size" => sync_redshift_size, "queue_length" => sync_redshift_length, }, } queue = { "copy_queue" => { "num_items" => copy_num }, "query_queue" => { "num_items" => query_num }, } else buffer = { "redshift" => { "buffer_size" => redshift_size, "queue_length" => redshift_length, }, } queue = { "copy_queue" => { "num_items" => copy_num }, } end { "complete" => complete, "state" => state, "stat" => { "buffer" => buffer, "queue" => queue }, "message" => message, "success" => true } end describe '#buffer_stat' do subject { subject_object.buffer_stat(data_entry_id, options) } let(:result1) { build_result(complete1, state1, proxy_size1, proxy_length1, redshift_size1, redshift_length1, sync_redshift_size1, sync_redshift_length1, copy_num1, query_num1, message1) } let(:complete1) { false } let(:state1) { "processing" } let(:proxy_size1) { 1 } let(:proxy_length1) { 3 } let(:redshift_size1) { 5 } let(:redshift_length1) { 7 } let(:sync_redshift_size1) { 11 } let(:sync_redshift_length1) { 13 } let(:copy_num1) { 17 } let(:query_num1) { 19 } let(:message1) { double('message1') } let(:message2) { double('message2') } shared_examples "calling api once and return expected result" do it do expect(api_client).to receive(:post). with("/data_entries/#{data_entry_id}/buffer_stat/", nil, tables: expected_tables). and_return(api_result) expect(subject).to eq expected_result end end context "with no tables" do let(:tables) { nil } let(:expected_tables) { '' } let(:api_result) { result1 } let(:expected_result) { result1 } let(:message) { message1 } it_behaves_like "calling api once and return expected result" end context "with empty table list" do let(:tables) { [] } let(:expected_tables) { '' } let(:api_result) { result1 } let(:expected_result) { result1 } let(:message) { message1 } it_behaves_like "calling api once and return expected result" end context "with less than 100 tables" do let(:tables) { %w[a b] } let(:expected_tables) { "a,b" } let(:api_result) { result1 } let(:expected_result) { result1 } it_behaves_like "calling api once and return expected result" context 'when buffer is empty' do let(:proxy_size1) { 0 } let(:proxy_length1) { 0 } let(:redshift_size1) { 0 } let(:redshift_length1) { 0 } let(:sync_redshift_size1) { 0 } let(:sync_redshift_length1) { 0 } let(:api_result) { result1 } context 'when queue is empty' do let(:copy_num1) { 0 } let(:query_num1) { 0 } let(:expected_result) { build_result(true, "complete", proxy_size1, proxy_length1, redshift_size1, redshift_length1, sync_redshift_size1, sync_redshift_length1, copy_num1, query_num1, message1) } it_behaves_like "calling api once and return expected result" end context 'when queue is not empty' do let(:expected_result) { build_result(false, "uploading", proxy_size1, proxy_length1, redshift_size1, redshift_length1, sync_redshift_size1, sync_redshift_length1, copy_num1, query_num1, message1) } it_behaves_like "calling api once and return expected result" end end context 'when buffer is not empty' do context 'when queue is empty' do let(:copy_num1) { 0 } let(:query_num1) { 0 } let(:expected_result) { build_result(false, "processing", proxy_size1, proxy_length1, redshift_size1, redshift_length1, sync_redshift_size1, sync_redshift_length1, copy_num1, query_num1, message1) } it_behaves_like "calling api once and return expected result" end end end context "with more than 20 tables" do let(:tables) { 30.times.collect{|i| "tbl#{i}"} } let(:expected_tables1) { tables[0...20].join(",") } let(:expected_tables2) { tables[20..-1].join(",") } let(:expected_message) { double('expected_message') } context "when no error" do shared_examples "calling api twice and return combined result" do it do expect(api_client).to receive(:post). with("/data_entries/#{data_entry_id}/buffer_stat/", nil, tables: expected_tables1). and_return(api_result1) expect(api_client).to receive(:post). with("/data_entries/#{data_entry_id}/buffer_stat/", nil, tables: expected_tables2). and_return(api_result2) expect(subject_object).to receive(:build_message). and_return(expected_message) expect(subject).to eq expected_result end end context "with Sync entry" do let(:api_result1) { build_result(complete1, state1, proxy_size1, proxy_length1, redshift_size1, redshift_length1, sync_redshift_size1, sync_redshift_length1, copy_num1, query_num1, message1) } let(:api_result2) { build_result(complete1, state1, proxy_size1, proxy_length1, redshift_size1, redshift_length1, sync_redshift_size1, sync_redshift_length1, copy_num1, query_num1, message2) } let(:expected_result) { build_result(complete1, state1, proxy_size1, proxy_length1, redshift_size1 + redshift_size1, redshift_length1 + redshift_length1, sync_redshift_size1 + sync_redshift_size1, sync_redshift_length1 + sync_redshift_length1, copy_num1 + copy_num1, query_num1 + query_num1, expected_message) } it_behaves_like "calling api twice and return combined result" end context "with AutoLoad entry" do let(:api_result1) { build_result(complete1, state1, nil, nil, redshift_size1, redshift_length1, nil, nil, copy_num1, query_num1, message1) } let(:api_result2) { build_result(complete1, state1, nil, nil, redshift_size1, redshift_length1, nil, nil, copy_num1, query_num1, message2) } let(:expected_result) { build_result(complete1, state1, nil, nil, redshift_size1 + redshift_size1, redshift_length1 + redshift_length1, nil, nil, copy_num1 + copy_num1, query_num1 + query_num1, expected_message) } it_behaves_like "calling api twice and return combined result" end end context "with an error with the first api call" do let(:api_result1) { { "complete" => false, "message" => expected_message, "success" => true, } } let(:api_result2) { result1 } let(:expected_result) { api_result1 } it do expect(api_client).to receive(:post). with("/data_entries/#{data_entry_id}/buffer_stat/", nil, tables: expected_tables1). and_return(api_result1) expect(subject_object).not_to receive(:build_message) expect(subject).to eq expected_result end end end end describe '#table_status' do subject { subject_object.table_status(data_entry_id, options) } let(:result1) { { "table_status" => [ status11, status12 ], "success" => true } } let(:status11) { double('status11') } let(:status12) { double('status12') } shared_examples "calling api with tables and return expected result" do it do expect(api_client).to receive(:post). with("/data_entries/#{data_entry_id}/table_status", nil, tables: expected_tables). and_return(api_result) expect(subject).to eq expected_result end end context "with no tables" do let(:tables) { nil } let(:expected_tables) { '' } let(:api_result) { result1 } let(:expected_result) { result1 } it_behaves_like "calling api with tables and return expected result" end context "with less than 100 tables" do let(:tables) { %w[a b] } let(:expected_tables) { 'a,b' } let(:api_result) { result1 } let(:expected_result) { result1 } it_behaves_like "calling api with tables and return expected result" end let(:result2) { { "table_status" => [ status21, status22 ], "success" => true } } let(:status21) { double('status21') } let(:status22) { double('status22') } context "with more than 20 tables" do let(:tables) { 30.times.collect {|i| "tbl#{i}"} } let(:expected_tables1) { tables[0...20].join(",") } let(:expected_tables2) { tables[20..-1].join(",") } it do expect(api_client).to receive(:post). with("/data_entries/#{data_entry_id}/table_status", nil, tables: expected_tables1). and_return(result1) expect(api_client).to receive(:post). with("/data_entries/#{data_entry_id}/table_status", nil, tables: expected_tables2). and_return(result2) expect(subject).to eq( "table_status" => [ status11, status12, status21, status22 ], "success" => true ) end end end end end end