@Test public void testBackpressure() throws Exception { createAndRegisterStats(); MockStatsSource.delay = 20; /* * Generate a bunch of requests, should get backpressure on some of them */ for (int ii = 0; ii < 30; ii++) { m_mvoltdb .getStatsAgent() .performOpsAction(m_mockConnection, 32, OpsSelector.STATISTICS, subselect("DR", 0)); } boolean hadBackpressure = false; for (int ii = 0; ii < 30; ii++) { ClientResponseImpl response = responses.take(); if (response.getStatus() == ClientResponse.GRACEFUL_FAILURE) { assertTrue("Too many pending stat requests".equals(response.getStatusString())); hadBackpressure = true; } } assertTrue(hadBackpressure); /* * Now having recieved all responses, it should be possible to collect the stats */ m_mvoltdb .getStatsAgent() .performOpsAction(m_mockConnection, 32, OpsSelector.STATISTICS, subselect("DR", 0)); ClientResponseImpl response = responses.take(); verifyResults(response); }
@Test public void testInvalidProcedure() throws IOException { ByteBuffer msg = createMsg("hellooooo", 1); ClientResponseImpl resp = m_ci.handleRead(msg, m_handler, m_cxn); assertNotNull(resp); assertEquals(ClientResponse.UNEXPECTED_FAILURE, resp.getStatus()); }
@Test public void testPolicyRejection() throws IOException { // incorrect parameters to @AdHoc proc ByteBuffer msg = createMsg("@AdHoc", 1, 3, 3); ClientResponseImpl resp = m_ci.handleRead(msg, m_handler, m_cxn); assertNotNull(resp); assertEquals(ClientResponse.GRACEFUL_FAILURE, resp.getStatus()); }
@Test public void testRejectDupInvocation() throws IOException { // by default, the mock initiator returns false for createTransaction() ByteBuffer msg = createMsg(12345l, "hello", 1); ClientResponseImpl resp = m_ci.handleRead(msg, m_handler, m_cxn); assertNotNull(resp); assertEquals(ClientResponse.UNEXPECTED_FAILURE, resp.getStatus()); }
@Test public void testNegativeUpdateCatalog() throws IOException { ByteBuffer msg = createMsg("@UpdateApplicationCatalog", new Integer(1), new Long(0)); ClientResponseImpl resp = m_ci.handleRead(msg, m_handler, m_cxn); // expect an error response from handleRead. assertNotNull(resp); assertTrue(resp.getStatus() != 0); }
@Test public void testPausedMode() throws IOException { // pause the node when(m_volt.getMode()).thenReturn(OperationMode.PAUSED); ByteBuffer msg = createMsg("hello", 1); ClientResponseImpl resp = m_ci.handleRead(msg, m_handler, m_cxn); assertNotNull(resp); assertEquals(ClientResponse.SERVER_UNAVAILABLE, resp.getStatus()); when(m_volt.getMode()).thenReturn(OperationMode.RUNNING); }
@Test public void testAdminProcsOnNonAdminPort() throws IOException { ByteBuffer msg = createMsg("@Pause"); ClientResponseImpl resp = m_ci.handleRead(msg, m_handler, m_cxn); assertNotNull(resp); assertEquals(ClientResponse.UNEXPECTED_FAILURE, resp.getStatus()); msg = createMsg("@Resume"); resp = m_ci.handleRead(msg, m_handler, m_cxn); assertNotNull(resp); assertEquals(ClientResponse.UNEXPECTED_FAILURE, resp.getStatus()); }
@Test public void testInvalidStatisticsSubselector() throws Exception { createAndRegisterStats(); m_mvoltdb .getStatsAgent() .performOpsAction(m_mockConnection, 32, OpsSelector.STATISTICS, subselect("CRAZY", 0)); ClientResponseImpl response = responses.take(); assertEquals(ClientResponse.GRACEFUL_FAILURE, response.getStatus()); assertEquals( "First argument to @Statistics must be a valid STRING selector, instead was CRAZY", response.getStatusString()); System.out.println(response.toJSONString()); }
@Test public void testCollectDRStats() throws Exception { createAndRegisterStats(); m_mvoltdb .getStatsAgent() .performOpsAction(m_mockConnection, 32, OpsSelector.STATISTICS, subselect("DR", 0)); ClientResponseImpl response = responses.take(); assertEquals(ClientResponse.SUCCESS, response.getStatus()); VoltTable results[] = response.getResults(); System.out.println(results[0]); System.out.println(results[1]); verifyResults(response); }
private void verifyResults(ClientResponseImpl response) { VoltTable results[] = response.getResults(); assertEquals(2, results.length); Set<Integer> pValues = new HashSet<Integer>(); pValues.add(45); pValues.add(44); pValues.add(43); pValues.add(42); while (results[0].advanceRow()) { assertTrue(pValues.contains((int) results[0].getLong(0))); assertTrue(pValues.contains(Integer.valueOf(results[0].getString(1)))); } Set<Integer> c1Values = pValues; Set<Integer> c2Values = new HashSet<Integer>(); c2Values.add(43); c2Values.add(44); while (results[1].advanceRow()) { assertTrue(c1Values.contains(Integer.valueOf(results[1].getString(0)))); assertTrue(c2Values.contains((int) results[1].getLong(1))); } }
@Test public void testCollectionTimeout() throws Exception { createAndRegisterStats(); StatsAgent.OPS_COLLECTION_TIMEOUT = 300; MockStatsSource.delay = 200; m_mvoltdb .getStatsAgent() .performOpsAction(m_mockConnection, 32, OpsSelector.STATISTICS, subselect("DR", 0)); ClientResponseImpl response = responses.take(); assertEquals(ClientResponse.GRACEFUL_FAILURE, response.getStatus()); VoltTable results[] = response.getResults(); assertEquals(0, results.length); System.out.println(response.getStatusString()); assertEquals( "OPS request hit sixty second timeout before all responses were received", response.getStatusString()); }
@Test public void testCollectUnavailableStats() throws Exception { for (StatsSelector selector : StatsSelector.values()) { m_mvoltdb .getStatsAgent() .performOpsAction( m_mockConnection, 32, OpsSelector.STATISTICS, subselect(selector.name(), 0)); ClientResponseImpl response = responses.take(); assertEquals(ClientResponse.GRACEFUL_FAILURE, response.getStatus()); VoltTable results[] = response.getResults(); assertEquals(0, results.length); assertEquals( "Requested info \"" + selector.name() + "\" is not yet available or not " + "supported in the current configuration.", response.getStatusString()); } }
@Test public void testCollectSnapshotStatusStats() throws Exception { createAndRegisterStats(); m_mvoltdb .getStatsAgent() .performOpsAction( m_mockConnection, 32, OpsSelector.STATISTICS, subselect("SNAPSHOTSTATUS", 0)); ClientResponseImpl response = responses.take(); assertEquals(ClientResponse.SUCCESS, response.getStatus()); VoltTable results[] = response.getResults(); System.out.println(results[0]); while (results[0].advanceRow()) { String c1 = results[0].getString("c1"); String c2 = results[0].getString("c2"); if (c1.equalsIgnoreCase("RYANLOVES")) { assertEquals("THEYANKEES", c2); } else if (c1.equalsIgnoreCase("NOREALLY")) { assertEquals("ASKHIM", c2); } else { fail("Unexpected row in results: c1: " + c1 + ", c2: " + c2); } } }
public ClientResponseImpl call(Object... paramListIn) { // verify per-txn state has been reset assert (m_statusCode == ClientResponse.UNINITIALIZED_APP_STATUS_CODE); assert (m_statusString == null); assert (m_cachedRNG == null); // reset the hash of results m_inputCRC.reset(); // use local var to avoid warnings about reassigning method argument Object[] paramList = paramListIn; ClientResponseImpl retval = null; // assert no sql is queued assert (m_batch.size() == 0); try { m_statsCollector.beginProcedure(); byte status = ClientResponse.SUCCESS; VoltTable[] results = null; // inject sysproc execution context as the first parameter. if (isSystemProcedure()) { final Object[] combinedParams = new Object[paramList.length + 1]; combinedParams[0] = m_systemProcedureContext; for (int i = 0; i < paramList.length; ++i) combinedParams[i + 1] = paramList[i]; // swap the lists. paramList = combinedParams; } if (paramList.length != m_paramTypes.length) { m_statsCollector.endProcedure(false, true, null, null); String msg = "PROCEDURE " + m_procedureName + " EXPECTS " + String.valueOf(m_paramTypes.length) + " PARAMS, BUT RECEIVED " + String.valueOf(paramList.length); status = ClientResponse.GRACEFUL_FAILURE; return getErrorResponse(status, msg, null); } for (int i = 0; i < m_paramTypes.length; i++) { try { paramList[i] = ParameterConverter.tryToMakeCompatible( m_paramTypeIsPrimitive[i], m_paramTypeIsArray[i], m_paramTypes[i], m_paramTypeComponentType[i], paramList[i]); } catch (Exception e) { m_statsCollector.endProcedure(false, true, null, null); String msg = "PROCEDURE " + m_procedureName + " TYPE ERROR FOR PARAMETER " + i + ": " + e.toString(); status = ClientResponse.GRACEFUL_FAILURE; return getErrorResponse(status, msg, null); } } boolean error = false; boolean abort = false; // run a regular java class if (m_catProc.getHasjava()) { try { if (log.isTraceEnabled()) { log.trace( "invoking... procMethod=" + m_procMethod.getName() + ", class=" + getClass().getName()); } try { Object rawResult = m_procMethod.invoke(m_procedure, paramList); results = getResultsFromRawResults(rawResult); } catch (IllegalAccessException e) { // If reflection fails, invoke the same error handling that other exceptions do throw new InvocationTargetException(e); } log.trace("invoked"); } catch (InvocationTargetException itex) { // itex.printStackTrace(); Throwable ex = itex.getCause(); if (ex instanceof VoltAbortException && !(ex instanceof EEException)) { abort = true; } else { error = true; } if (ex instanceof Error) { m_statsCollector.endProcedure(false, true, null, null); throw (Error) ex; } retval = getErrorResponse(ex); } } // single statement only work // (this could be made faster, but with less code re-use) else { assert (m_catProc.getStatements().size() == 1); try { m_cachedSingleStmt.params = getCleanParams(m_cachedSingleStmt.stmt, paramList); if (getHsqlBackendIfExists() != null) { // HSQL handling CatalogMap<StmtParameter> sparamsMap = m_cachedSingleStmt.stmt.catStmt.getParameters(); List<StmtParameter> sparams = CatalogUtil.getSortedCatalogItems(sparamsMap, "index"); VoltTable table = getHsqlBackendIfExists() .runSQLWithSubstitutions( m_cachedSingleStmt.stmt, m_cachedSingleStmt.params, sparams); results = new VoltTable[] {table}; } else { m_batch.add(m_cachedSingleStmt); results = voltExecuteSQL(true); } } catch (SerializableException ex) { retval = getErrorResponse(ex); } } // Record statistics for procedure call. StoredProcedureInvocation invoc = (m_txnState != null ? m_txnState.getInvocation() : null); ParameterSet paramSet = (invoc != null ? invoc.getParams() : null); m_statsCollector.endProcedure(abort, error, results, paramSet); // don't leave empty handed if (results == null) results = new VoltTable[0]; if (retval == null) retval = new ClientResponseImpl(status, m_statusCode, m_statusString, results, null); int hash = (int) m_inputCRC.getValue(); if ((retval.getStatus() == ClientResponse.SUCCESS) && (hash != 0)) { retval.setHash(hash); } if ((m_txnState != null) && // may be null for tests (m_txnState.getInvocation() != null) && (m_txnState.getInvocation().getType() == ProcedureInvocationType.REPLICATED)) { retval.convertResultsToHashForDeterminism(); } } finally { // finally at the call(..) scope to ensure params can be // garbage collected and that the queue will be empty for // the next call m_batch.clear(); // reset other per-txn state m_txnState = null; m_statusCode = ClientResponse.UNINITIALIZED_APP_STATUS_CODE; m_statusString = null; m_cachedRNG = null; m_cachedSingleStmt.params = null; m_cachedSingleStmt.expectation = null; m_seenFinalBatch = false; } return retval; }