/**
   * Test for service action.
   *
   * <p>Replicates the behavior of {@link FBStatisticsManager#getHeaderPage()}.
   */
  @Test
  public void testStartServiceAction() throws Exception {
    FBManager fbManager = createFBManager();
    defaultDatabaseSetUp(fbManager);
    try (JnaService service = factory.serviceConnect(connectionInfo)) {
      service.attach();

      ServiceRequestBuffer actionSrb = service.createServiceRequestBuffer();
      actionSrb.addArgument(isc_action_svc_db_stats);
      actionSrb.addArgument(isc_spb_dbname, getDatabasePath());
      actionSrb.addArgument(isc_spb_options, isc_spb_sts_hdr_pages);

      service.startServiceAction(actionSrb);

      ServiceRequestBuffer infoSrb = service.createServiceRequestBuffer();
      infoSrb.addArgument(isc_info_svc_to_eof);
      int bufferSize = 1024;
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      boolean processing = true;
      while (processing) {
        byte[] buffer = service.getServiceInfo(null, infoSrb, bufferSize);

        switch (buffer[0]) {
          case isc_info_svc_to_eof:
            int dataLength = iscVaxInteger2(buffer, 1);
            if (dataLength == 0) {
              if (buffer[3] != isc_info_end) {
                throw new SQLException("Unexpected end of stream reached.");
              } else {
                processing = false;
                break;
              }
            }
            bos.write(buffer, 3, dataLength);
            break;
          case isc_info_truncated:
            bufferSize = bufferSize * 2;
            break;
          case isc_info_end:
            processing = false;
            break;
        }
      }
      String headerPage = service.getEncoding().decodeFromCharset(bos.toByteArray());
      assertThat(
          "Expected database header page content",
          headerPage,
          allOf(
              startsWith("\nDatabase"),
              containsString("Database header page information"),
              endsWith("*END*\n")));
    } finally {
      defaultDatabaseTearDown(fbManager);
    }
  }
  @Test
  public void doubleAttach() throws Exception {
    expectedException.expect(SQLException.class);
    expectedException.expectMessage(equalTo("Already attached to a service"));

    try (JnaService service = factory.serviceConnect(connectionInfo)) {
      service.attach();

      // Second attach should throw exception
      service.attach();
    }
  }
  @Test
  public void testBasicStatusVectorProcessing_wrongService() throws Exception {
    // set invalid database
    final String invalidServiceName = "doesnotexist";
    connectionInfo.setServiceName(invalidServiceName);
    try (JnaService service = factory.serviceConnect(connectionInfo)) {

      expectedException.expect(
          allOf(isA(SQLException.class), fbMessageStartsWith(ISCConstants.isc_service_att_err)));

      service.attach();
    }
  }
  @Test
  public void testBasicAttach() throws Exception {
    try (JnaService service = factory.serviceConnect(connectionInfo)) {
      service.attach();

      assertTrue("Expected isAttached() to return true", service.isAttached());
      assertThat("Expected non-zero connection handle", service.getHandle(), not(equalTo(0)));
      assertNotNull("Expected version string to be not null", service.getServerVersion());
      assertNotEquals(
          "Expected version should not be invalid",
          GDSServerVersion.INVALID_VERSION,
          service.getServerVersion());
    }
  }
  @Test
  public void basicStatusVectorProcessing_wrongLogin() throws Exception {
    // set invalid password
    connectionInfo.setPassword("abcd");
    try (JnaService service = factory.serviceConnect(connectionInfo)) {

      expectedException.expect(
          allOf(
              isA(SQLException.class),
              message(startsWith(getFbMessage(ISCConstants.isc_login))),
              errorCode(equalTo(ISCConstants.isc_login))));

      service.attach();
    }
  }