@DataBoundConstructor
  public WwpassSecurityRealm(String certFile, String keyFile, String name, boolean allowsSignup) {

    this.disableSignup = !allowsSignup;

    this.name = name;

    if (certFile != null && !certFile.isEmpty() && keyFile != null && !keyFile.isEmpty()) {
      this.certFile = certFile;
      this.keyFile = keyFile;
    } else {
      if (System.getProperty("os.name").startsWith("Windows")) {
        this.certFile = DEFAULT_CERT_FILE_WINDOWS;
        this.keyFile = DEFAULT_KEY_FILE_WINDOWS;
      } else if (System.getProperty("os.name").startsWith("Linux")) {
        this.certFile = DEFAULT_CERT_FILE_LINUX;
        this.keyFile = DEFAULT_KEY_FILE_LINUX;
      } else {
        LOGGER.severe(Messages.WwpassSession_UnsupportedOsError());
        throw new Failure(Messages.WwpassSession_AuthError());
      }
    }

    if (!hasSomeUser()) {
      // if Hudson is newly set up with the security realm and there's no user account created yet,
      // insert a filter that asks the user to create one
      try {
        PluginServletFilter.addFilter(CREATE_FIRST_USER_FILTER);
      } catch (ServletException e) {
        throw new AssertionError(e); // never happen because our Filter.init is no-op
      }
    }
  }
  public void testSelfExcludingJobs() throws Exception {

    BuildBlockerProperty theProperty = new BuildBlockerProperty();
    theProperty.setBlockingJobs("SelfExcluding_.*");

    FreeStyleProject theJob1 = createFreeStyleProject("SelfExcluding_Job1");
    theJob1.addProperty(theProperty);
    assertTrue(theJob1.getBuilds().isEmpty());

    FreeStyleProject theJob2 = createFreeStyleProject("SelfExcluding_Job2");
    theJob2.addProperty(theProperty);
    assertTrue(theJob1.getBuilds().isEmpty());

    // allow executing two simultanious jobs
    int theOldNumExecutors = Hudson.getInstance().getNumExecutors();
    Hudson.getInstance().setNumExecutors(2);

    Future<FreeStyleBuild> theFuture1 = theJob1.scheduleBuild2(0);
    Future<FreeStyleBuild> theFuture2 = theJob2.scheduleBuild2(0);

    long theStartTime = System.currentTimeMillis();
    long theEndTime = theStartTime;
    while ((!theFuture1.isDone() || !theFuture2.isDone()) && theEndTime < theStartTime + 5000) {
      theEndTime = System.currentTimeMillis();
    }

    // if more then five seconds have passed, we assume its a deadlock.
    assertTrue(theEndTime < theStartTime + 5000);

    // restore changed settings
    Hudson.getInstance().setNumExecutors(theOldNumExecutors);
    theJob2.delete();
    theJob1.delete();
  }
    @Override
    @GuardedBy("hudson.model.Queue.lock")
    public long check(final SlaveComputer c) {
      if (c.isOffline() && c.isLaunchSupported()) {
        final HashMap<Computer, Integer> availableComputers = new HashMap<Computer, Integer>();
        for (Computer o : Jenkins.getInstance().getComputers()) {
          if ((o.isOnline() || o.isConnecting()) && o.isPartiallyIdle() && o.isAcceptingTasks()) {
            final int idleExecutors = o.countIdle();
            if (idleExecutors > 0) availableComputers.put(o, idleExecutors);
          }
        }

        boolean needComputer = false;
        long demandMilliseconds = 0;
        for (Queue.BuildableItem item : Queue.getInstance().getBuildableItems()) {
          // can any of the currently idle executors take this task?
          // assume the answer is no until we can find such an executor
          boolean needExecutor = true;
          for (Computer o : Collections.unmodifiableSet(availableComputers.keySet())) {
            Node otherNode = o.getNode();
            if (otherNode != null && otherNode.canTake(item) == null) {
              needExecutor = false;
              final int availableExecutors = availableComputers.remove(o);
              if (availableExecutors > 1) {
                availableComputers.put(o, availableExecutors - 1);
              } else {
                availableComputers.remove(o);
              }
              break;
            }
          }

          // this 'item' cannot be built by any of the existing idle nodes, but it can be built by
          // 'c'
          Node checkedNode = c.getNode();
          if (needExecutor && checkedNode != null && checkedNode.canTake(item) == null) {
            demandMilliseconds = System.currentTimeMillis() - item.buildableStartMilliseconds;
            needComputer = demandMilliseconds > inDemandDelay * 1000 * 60 /*MINS->MILLIS*/;
            break;
          }
        }

        if (needComputer) {
          // we've been in demand for long enough
          logger.log(
              Level.INFO,
              "Launching computer {0} as it has been in demand for {1}",
              new Object[] {c.getName(), Util.getTimeSpanString(demandMilliseconds)});
          c.connect(false);
        }
      } else if (c.isIdle()) {
        final long idleMilliseconds = System.currentTimeMillis() - c.getIdleStartMilliseconds();
        if (idleMilliseconds > idleDelay * 1000 * 60 /*MINS->MILLIS*/) {
          // we've been idle for long enough
          logger.log(
              Level.INFO,
              "Disconnecting computer {0} as it has been idle for {1}",
              new Object[] {c.getName(), Util.getTimeSpanString(idleMilliseconds)});
          c.disconnect(new OfflineCause.IdleOfflineCause());
        } else {
          // no point revisiting until we can be confident we will be idle
          return TimeUnit.MILLISECONDS.toMinutes(
              TimeUnit.MINUTES.toMillis(idleDelay) - idleMilliseconds);
        }
      }
      return 1;
    }
  @Override
  public BuildWrapper.Environment setUp(
      AbstractBuild build, Launcher launcher, BuildListener listener)
      throws IOException, InterruptedException {
    final PrintStream logger = listener.getLogger();

    final DeviceFarmApi api = new DeviceFarmApiImpl();
    long start = System.currentTimeMillis();

    try {
      EnvVars environment = build.getEnvironment(listener);
      String expendedTag = environment.expand(tag);

      log(logger, Messages.TRYING_TO_CONNECT_API_SERVER(deviceApiUrl, expendedTag));
      api.connectApiServer(
          logger,
          deviceApiUrl,
          expendedTag,
          build.getProject().getAbsoluteUrl() + build.getNumber());

      final RemoteDevice reserved =
          api.waitApiResponse(
              logger, DEVICE_WAIT_TIMEOUT_IN_MILLIS, DEVICE_READY_CHECK_INTERVAL_IN_MS);
      log(
          logger,
          Messages.DEVICE_IS_READY(passedSeconds(start), reserved.ip, reserved.port, reserved.url));

      if (descriptor == null) {
        descriptor = Hudson.getInstance().getDescriptorByType(DescriptorImpl.class);
      }

      // Substitute environment and build variables into config
      final String androidHome = discoverAndroidSdkHome(build, launcher, listener);
      log(logger, Messages.USING_SDK(androidHome));

      AndroidSdk sdk = new AndroidSdk(androidHome, androidHome);
      final AndroidDeviceContext device =
          new AndroidDeviceContext(build, launcher, listener, sdk, reserved.ip, reserved.port);
      // disconnect first to workaround previous error
      device.disconnect();

      // connect device with adb
      device.connect(DEVICE_CONNECT_TIMEOUT_IN_MILLIS);

      device.waitDeviceReady(logger, DEVICE_CONNECT_TIMEOUT_IN_MILLIS, 1000);
      // check availability
      device.devices();

      // unlock screen
      device.unlockScreen();

      // Start dumping logcat to temporary file
      final LogcatCollector logcatCollector = new LogcatCollector(build, device);
      logcatCollector.start();

      return new BuildWrapper.Environment() {
        @Override
        public void buildEnvVars(Map<String, String> env) {
          env.put("ANDROID_IP", device.ip());
          env.put("ANDROID_HOME", androidHome);
          env.put("ANDROID_SDK_HOME", androidHome);
          env.put("ANDROID_PORT", Integer.toString(device.port()));
          env.put("ANDROID_SERIAL", device.serial());
        }

        @Override
        public boolean tearDown(AbstractBuild build, BuildListener listener)
            throws IOException, InterruptedException {
          cleanUp(build, device, api, logcatCollector);

          return true;
        }
      };

    } catch (FailedToConnectApiServerException e) {
      log(logger, Messages.FAILED_TO_CONNECT_API_SERVER());
    } catch (MalformedResponseException e) {
      log(logger, Messages.FAILED_TO_PARSE_DEVICE_FARM_RESPONSE());
    } catch (TimeoutException e) {
      log(logger, Messages.DEVICE_WAIT_TIMEOUT(passedSeconds(start)));
    } catch (NoDeviceAvailableException e) {
      log(logger, Messages.NO_SUCH_DEVICE());
    }

    build.setResult(Result.NOT_BUILT);
    cleanUp(null, null, api, null);
    return null;
  }
 private long passedSeconds(long start) {
   return (System.currentTimeMillis() - start) / 1000;
 }