2010-05-13 35 views
9

Tôi mới sử dụng Java và junit. Tôi có đoạn mã sau mà tôi muốn kiểm tra. Sẽ đánh giá cao nếu bạn có thể gửi ý tưởng của bạn về những gì là cách tốt nhất để đi về thử nghiệm nó.Cách kiểm tra đơn vị mã được đồng bộ hóa

Về cơ bản, mã sau đây là về việc chọn biểu mẫu nhà lãnh đạo một Cụm. Các nhà lãnh đạo nắm giữ một khóa trên bộ nhớ cache được chia sẻ và dịch vụ của các nhà lãnh đạo được tiếp tục và xử lý nếu nó bằng cách nào đó mất khóa trên bộ nhớ cache.

Làm cách nào để đảm bảo rằng người dẫn đầu/chuỗi vẫn giữ khóa trên bộ nhớ cache và một chuỗi khác không thể khôi phục các dịch vụ của nó trong khi lần đầu tiên được thực thi?

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; 
} 
+0

http://today.java.net/article/2003/07/12/multithreaded-tests-junit http://www.junit.org/node/54 – Bozho

Trả lời

3

Để thay thế cho các khuôn khổ kiểm tra (hoặc để mở rộng thêm trên đầu trang của JUnit, nếu bạn đang sử dụng đó) chỉ là một số mã cũ đồng bằng:

  • Tạo nhiều chủ đề và áp dụng chúng vào thói quen này.
  • Lặp qua các chủ đề và kiểm tra từng chủ đề cho đến khi bạn tìm ra ai là người lãnh đạo.
  • Áp dụng các thay đổi môi trường khác nhau (bao gồm cả thời gian trôi qua) cho trạng thái chương trình của bạn và làm lại bài kiểm tra. Liệu người lãnh đạo vẫn là người lãnh đạo?
  • Bây giờ, buộc người lãnh đạo thoái vị (tiêu diệt chủ đề đó hoặc thứ gì đó). Một chuỗi khác có tiếp quản không?
4

Nếu bạn không quá cụ thể về việc sử dụng JUnit, thì bạn có thể sử dụng khung TestNG. Họ có hỗ trợ đa luồng.

Các vấn đề liên quan