Tôi đang cố gắng tìm ra cách triển khai thử nghiệm tích hợp nhiều gói trong OSGi bằng cách sử dụng JUnit.Sử dụng các dịch vụ khai báo OSGi trong ngữ cảnh của một thử nghiệm JUnit
Với thử nghiệm tích hợp, tôi có nghĩa là tạo một tập hợp con các gói để tự động xác thực chức năng trong hệ thống con đó.
Chúng tôi đang chạy Equinox và sử dụng Eclipse làm toolchain. Eclipse cung cấp tùy chọn "Run as JUnit Plug-in" mang khung OSGi lên và khởi tạo các gói cấu hình, vì vậy tôi đoán đây là đường dẫn để làm theo, nhưng tôi không tìm cách chèn các tham chiếu DS vào các thử nghiệm của mình. Tôi đã nhìn thấy việc sử dụng ServiceTracker như một phương tiện có lập trình để truy cập vào các gói dịch vụ khác nhau, nhưng điều đó đánh bại mục đích của việc có DS, phải không?
Tôi chỉ mới bắt đầu với OSGI, vì vậy tôi nghĩ tôi chỉ thiếu một số câu đố có thể cho phép tôi đưa các bài kiểm tra nhiều bó của mình lại với nhau.
Bất kỳ ý tưởng nào?
Cảm ơn, Gerard.
* EDIT: GIẢI PHÁP *
Sau khi nhìn sâu hơn vào vấn đề này, cuối cùng tôi đã tìm ra cách để đặt này thử nghiệm hội nhập mult-bó tại chỗ bằng cách sử dụng plug-in JUnit tính năng:
Đối các dịch vụ động tiêm để làm việc, người ta phải tạo ra một tập tin định nghĩa dịch vụ, nơi phụ thuộc tiêm phải được khai báo, vì nó thường được thực hiện khi làm việc với DS. Tệp này đi (thường) trong thư mục OSGI-INF/
. ví dụ. OSGI-INF/service.xml
service.xml phải khai báo phụ thuộc yêu cầu cho thử nghiệm này, nhưng không cung cấp một dịch vụ của riêng nó:
service.xml
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="MyTest" activate="startup" deactivate="shutdown">
<implementation class="com.test.functionaltest.MyTester"/>
<reference name="OtherService" interface="com.product.service.FooService" policy="static" cardinality="1..1" bind="onServiceUp" unbind="onServiceDown"/>
</scr:component>
này sẽ hướng dẫn DS để tiêm phụ thuộc vào FooService sử dụng phương pháp kê khai onServiceUp. onServiceDown phải được thực hiện khi nó được gọi trong giai đoạn shutdown OSGi sau khi chạy thử nghiệm.
com.test.functionaltest.MyTester chứa các phương pháp thử nghiệm được thực hiện, theo các thực tiễn JUnit điển hình.
Đến đây, tất cả đều là 'theo sách'. Tuy nhiên, nếu Junit được chạy, nó sẽ ném NullPointerException khi truy cập một tham chiếu đến FooService. Lý do cho điều đó là khung công tác OSGi đang trong tình trạng chạy đua với bối cảnh Á hậu thử nghiệm JUnit, và thường, người chạy thử nghiệm Junit thắng cuộc đua đó, thực hiện các kiểm tra trước khi tham chiếu đến dịch vụ được yêu cầu được tiêm.
Để giải quyết tình huống này, bắt buộc phải thực hiện kiểm tra Junit để đợi thời gian chạy OSGi thực hiện công việc của mình. Tôi đã giải quyết vấn đề này bằng cách sử dụng một CountDownLatch, được khởi tạo cho số lượng các dịch vụ phụ thuộc được yêu cầu trong thử nghiệm. Sau đó, mỗi phương pháp tiêm phụ thuộc đếm ngược và khi chúng được thực hiện xong, thử nghiệm sẽ bắt đầu. Mã này trông như thế này:
private static CountDownLatch dependencyLatch = new CountDownLatch(1);// 1 = number of dependencies required
static FooService fooService = null;
public void onFooServiceUp(FooService service) {
fooService = service;
dependencyLatch.countDown();
}
Lưu ý rằng fooService
tài liệu tham khảo cần phải được tĩnh để cho phép chia sẻ các tài liệu tham khảo phục vụ giữa OSGi và bối cảnh thực hiện JUnit. CountDownLatch cung cấp cơ chế đồng bộ hóa cấp cao để xuất bản an toàn tài liệu tham khảo được chia sẻ này.
Sau đó, kiểm tra sự phụ thuộc nên được bổ sung trước khi thực hiện kiểm tra:
@Before
public void dependencyCheck() {
// Wait for OSGi dependencies
try {
dependencyLatch.await(10, TimeUnit.SECONDS);
// Dependencies fulfilled
} catch (InterruptedException ex) {
fail("OSGi dependencies unfulfilled");
}
}
Bằng cách này, khuôn khổ Junit đợi cho dịch vụ OSGi DS để tiêm phụ thuộc hay thất bại sau khi thời gian chờ.
Tôi mất khá nhiều thời gian để hoàn toàn tìm ra điều này. Tôi hy vọng nó sẽ tiết kiệm một số nhức đầu cho các lập trình viên trong tương lai.
Chắc chắn, đó là tùy chọn "chạy dưới dạng plugin JUnit" mà tôi đã đề cập, nhưng dường như không đủ để nhận được Dịch vụ khai báo. tức là bạn khai báo phương pháp ràng buộc ở đâu? Ngoài ra còn có câu hỏi về ngữ cảnh. Liệu việc tiêm sẽ xảy ra trên bối cảnh Junit? Nếu vậy, cơ chế đó hoạt động như thế nào? – maasg
Giống như bạn sử dụng DS trong ứng dụng. Bạn sẽ cần thêm gói DS, thao tác này quét các gói khác khi chúng được tải và quản lý hệ thống dây điện. Các ràng buộc DS được khai báo trong thành phần xml trong OSGI-INF trong jar của gói. Xem http://www.vogella.de/articles/OSGi/article.html#declarativeservices_run để có giải thích về cách sử dụng DS trong các dự án Trình cắm thêm của Eclipse. HTH – earcam
Cảm ơn bạn đã đề xuất. Các phương pháp tiêm DS không được gọi trong bối cảnh chạy plugin Junit. OSG-INF của tôi khai báo chính xác chúng. – maasg