当前位置: 首页 > 面试题库 >

如何对同步代码进行单元测试

羊舌墨一
2023-03-14
问题内容

我是Java和junit的新手。我有以下要测试的代码。如果您能提出有关测试它的最佳方法的想法,将不胜感激。

基本上,以下代码与从集群中选出领导者有关。领导者在共享缓存上持有锁,并且如果领导者以某种方式释放了对缓存的锁定,则领导者的服务将恢复并处置。

我如何确保领导者/线程仍保持对缓存的锁定,并且在执行第一个线程时另一个线程无法恢复其服务?

public interface ContinuousService {

public void resume();
public void pause();
}


public abstract class ClusterServiceManager {
private volatile boolean leader = false;
private volatile boolean electable = true;
private List<ContinuousService> services;

protected synchronized void onElected() {
    if (!leader) {
        for (ContinuousService service : services) {
            service.resume();
        }
        leader = true;
    }
}

protected synchronized void onDeposed() {
    if (leader) {
        for (ContinuousService service : services) {
            service.pause();
        }
        leader = false;
    }
}

public void setServices(List<ContinuousService> services) {
    this.services = services;
}

@ManagedAttribute
public boolean isElectable() {
    return electable;
}

@ManagedAttribute
public boolean isLeader() {
    return leader;
}



public class TangosolLeaderElector extends ClusterServiceManager implements Runnable {
private static final Logger log = LoggerFactory.getLogger(TangosolLeaderElector.class);
private String election;
private long electionWaitTime= 5000L;

private NamedCache cache;

public void start() {
    log.info("Starting LeaderElector ({})",election);
    Thread t = new Thread(this, "LeaderElector ("+election+")");
    t.setDaemon(true);
    t.start();
}

public void run() {
    // Give the connection a chance to start itself up
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {}

    boolean wasElectable = !isElectable();
    while (true) {
        if (isElectable()) {
            if (!wasElectable) {
                log.info("Leadership requested on election: {}",election);
                wasElectable = isElectable();
            }
            boolean elected = false;
            try {
                // Try and get the lock on the LeaderElectorCache for the current election
                if (!cache.lock(election, electionWaitTime)) {
                    // We didn't get the lock. cycle round again. 
                    // This code to ensure we check the electable flag every now & then
                    continue;
                }
                elected = true;
                log.info("Leadership taken on election: {}",election);
                onElected();

                // Wait here until the services fail in some way.
                while (true) {
                    try {
                        Thread.sleep(electionWaitTime);
                    } catch (InterruptedException e) {}
                    if (!cache.lock(election, 0)) {
                        log.warn("Cache lock no longer held for election: {}", election);
                        break;
                    } else if (!isElectable()) {
                        log.warn("Node is no longer electable for election: {}", election);
                        break;
                    }
                    // We're fine - loop round and go back to sleep.
                }
            } catch (Exception e) {
                if (log.isErrorEnabled()) {
                    log.error("Leadership election " + election + " failed (try bfmq logs for details)", e);
                }
            } finally {
                if (elected) {
                    cache.unlock(election);
                    log.info("Leadership resigned on election: {}",election);
                    onDeposed();
                }
                // On deposition, do not try and get re-elected for at least the standard wait time.
                try { Thread.sleep(electionWaitTime); } catch (InterruptedException e) {}
            }
        } else {
            // Not electable - wait a bit and check again.
            if (wasElectable) {
                log.info("Leadership NOT requested on election ({}) - node not electable",election);
                wasElectable = isElectable();
            }
            try {
                Thread.sleep(electionWaitTime);
            } catch (InterruptedException e) {}
        }
    }
}

public void setElection(String election) {
    this.election = election;
}

@ManagedAttribute
public String getElection() {
    return election;
}

public void setNamedCache(NamedCache nc) {
    this.cache = nc;
}

问题答案:

作为测试框架的替代方法(或使用JUnit的其他扩展,如果使用的话),它只是一些简单的旧代码:

  • 创建多个线程并将它们应用于此例程。
  • 遍历线程并测试每个线程,直到找出谁是领导者。
  • 程序的状态应用不同的环境变化(包括时间的流逝)并重做测试。领导者仍然是领导者吗?
  • 现在,强制领导退位(杀死该线程或其他东西)。另一个线程接管了吗?


 类似资料:
  • 问题内容: 我想问一下您首选的Java EE代码测试方法? 我发现只有三个项目,这些项目试图帮助在Java EE环境中编写单元测试: http://jakarta.apache.org/cactus/:上次发布时间:2009-01-18 http://www.junitee.org/:最新版本:2004-12-11 http://ejb3unit.sourceforge.net/:最新版本:200

  • 问题内容: 到目前为止,我似乎避免了测试多线程代码的噩梦,因为它似乎太多了。我想问一下人们如何去测试依赖于线程的代码才能成功执行,或者人们如何去测试那些仅在两个线程以给定方式交互时才会出现的问题? 对于当今的程序员来说,这似乎是一个非常关键的问题,将我们的知识集中在这一恕我直言上将很有用。 问题答案: 看,没有简单的方法可以做到这一点。我正在开发一个本质上是多线程的项目。事件来自操作系统,我必须同

  • 问题内容: 我目前正在编写Java客户端服务器应用程序。所以我想实现两个库,一个用于客户端,一个用于服务器。客户端服务器通信具有非常严格的协议,我不打算使用JUnit进行测试。 作为构建工具,我使用Maven和Husdon Server进行持续集成。 实际上,我对如何测试这些客户端/服务器库没有什么好主意。 我得到以下方法: 只需编写一个虚拟客户端来测试服务器,然后编写一个虚拟服务器来测试客户端。

  • 问题内容: 我有一段代码,期望用Java UUID()填充响应对象的一个​​属性。 如何从外部对代码进行单元测试以检查此行为?我不知道会在其中生成UUID。 需要测试的示例代码: 问题答案: Powermock和静态模拟是前进的道路。您将需要以下内容: 请注意,可以在带有@Before注释的方法中实现静态模拟,因此可以在需要UUID的所有测试用例中重新使用该静态模拟,以避免代码重复。 初始化静态模

  • 问题内容: 我想为一些连接到数据库,运行一个或多个查询然后处理结果的代码编写一些单元测试。(实际上没有使用数据库) 这里的另一个开发人员编写了我们自己的DataSource,Connection,Statement,PreparedStatement和ResultSet实现,这些实现将基于xml配置文件返回相应的对象。(我们可以使用伪造的数据源,并针对返回的结果集运行测试)。 我们在这里重新发明轮

  • 问题内容: 如何在单元测试中测试 hashCode()函数? 问题答案: 每当我覆盖equals和hash代码时,我都会按照Joshua Bloch在“ Effective Java”第3章中的建议编写单元测试。我确保equals和hash代码是自反的,对称的和可传递的。我还确保“不等于”对所有数据成员均正常工作。 当我检查对equals的调用时,我还要确保hashCode的行为符合预期。像这样: