Untitled
class YourClassNameTest { @Mock private YourDependency yourDependency; private YourClassName yourClass; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); yourClass = new YourClassName(yourDependency); } @Test void testIsExtraDataExistInS3_WhenMultipartFilesLengthIsNotOne() { // Arrange int featureId = 1; MultipartFile[] multipartFiles = new MultipartFile[0]; ExtraDataType type = ExtraDataType.TYPE1; // Act boolean result = yourClass.isExtraDataExistInS3(featureId, multipartFiles, type); // Assert assertFalse(result); verify(yourDependency, never()).isExtraDataExistInS3(anyString()); } @Test void testIsExtraDataExistInS3_WhenIOExceptionOccurs() throws IOException { // Arrange int featureId = 1; MultipartFile[] multipartFiles = {new MockMultipartFile("file.txt", new byte[0])}; ExtraDataType type = ExtraDataType.TYPE1; when(yourDependency.isExtraDataExistInS3(anyString())).thenReturn(true); // Act boolean result = yourClass.isExtraDataExistInS3(featureId, multipartFiles, type); // Assert assertFalse(result); verify(yourDependency, never()).isExtraDataExistInS3(anyString()); } @Test void testIsExtraDataExistInS3_WhenSuccess() throws IOException { // Arrange int featureId = 1; MultipartFile[] multipartFiles = {new MockMultipartFile("file.txt", new byte[0])}; ExtraDataType type = ExtraDataType.TYPE1; when(yourDependency.isExtraDataExistInS3(anyString())).thenReturn(true); // Act boolean result = yourClass.isExtraDataExistInS3(featureId, multipartFiles, type); // Assert assertTrue(result); ArgumentCaptor<String> filePathCaptor = ArgumentCaptor.forClass(String.class); verify(yourDependency).isExtraDataExistInS3(filePathCaptor.capture()); String expectedFilePath = getFilePath(featureId, "file.txt", type); assertEquals(expectedFilePath, filePathCaptor.getValue()); } } //////////////// private MockMultipartFile createMockMultipartFile(String filename, String content) { byte[] contentBytes = content.getBytes(); InputStream inputStream = new ByteArrayInputStream(contentBytes); return new MockMultipartFile("file", filename, null, inputStream); } ////////////////////// class YourClassNameTest { @Mock private ProceedingJoinPoint joinPoint; @Mock private FeatureExtraDataService featureExtraDataService; private YourClassName yourClass; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); yourClass = new YourClassName(featureExtraDataService); } @Test void testLogFeatureExtraDataUploaded_WhenExtraDataExists() throws Throwable { // Arrange int featureId = 1; MultipartFile[] multipartFiles = {createMockMultipartFile("test.txt", "Test file content")}; ExtraDataType type = ExtraDataType.TYPE_A; String endpointUrl = "http://example.com/endpoint"; when(featureExtraDataService.isExtraDataExistInS3(eq(featureId), eq(multipartFiles), eq(type))).thenReturn(true); when(joinPoint.proceed()).thenReturn(endpointUrl); // Act String result = yourClass.logFeatureExtraDataUploaded(joinPoint, featureId, multipartFiles, type); // Assert assertEquals(endpointUrl, result); ArgumentCaptor<Integer> featureIdCaptor = ArgumentCaptor.forClass(Integer.class); ArgumentCaptor<String> dataTypeCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<ChangeType> changeTypeCaptor = ArgumentCaptor.forClass(ChangeType.class); ArgumentCaptor<String> detailCaptor = ArgumentCaptor.forClass(String.class); verify(featureExtraDataService).isExtraDataExistInS3(featureIdCaptor.capture(), any(), eq(type)); verify(joinPoint).proceed(); verify(featureExtraDataService).saveChangeLog(eq(featureId), isNull(), dataTypeCaptor.capture(), changeTypeCaptor.capture(), detailCaptor.capture()); assertEquals(featureId, featureIdCaptor.getValue()); assertEquals(DataType.EXTRA_DATA.toString(), dataTypeCaptor.getValue()); assertEquals(ChangeType.UPDATED, changeTypeCaptor.getValue()); Map<String, String> expectedDetail = new HashMap<>(); expectedDetail.put("extraDataName", "endpoint"); assertEquals(expectedDetail.toString(), detailCaptor.getValue()); } @Test void testLogFeatureExtraDataUploaded_WhenExtraDataDoesNotExist() throws Throwable { // Arrange int featureId = 1; MultipartFile[] multipartFiles = {createMockMultipartFile("test.txt", "Test file content")}; ExtraDataType type = ExtraDataType.TYPE_A; String endpointUrl = "http://example.com/endpoint"; when(featureExtraDataService.isExtraDataExistInS3(eq(featureId), eq(multipartFiles), eq(type))).thenReturn(false); when(joinPoint.proceed()).thenReturn(endpointUrl); // Act String result = yourClass.logFeatureExtraDataUploaded(joinPoint, featureId, multipartFiles, type); // Assert assertEquals(endpointUrl, result); ArgumentCaptor<Integer> featureIdCaptor = ArgumentCaptor.forClass(Integer.class); ArgumentCaptor<String> dataTypeCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<ChangeType> changeTypeCaptor = ArgumentCaptor.forClass(ChangeType.class); ArgumentCaptor<String> detailCaptor = ArgumentCaptor.forClass(String.class); verify(featureExtraDataService).isExtraDataExistInS3(featureIdCaptor.capture(), any(), eq(type)); verify(joinPoint).proceed(); verify(featureExtraDataService).saveChangeLog(eq(featureId), isNull(), dataTypeCaptor.capture(), changeTypeCaptor.capture(), detailCaptor.capture()); assertEquals(featureId, featureIdCaptor.getValue()); assertEquals(DataType.EXTRA_DATA.toString(), dataTypeCaptor.getValue()); assertEquals(ChangeType.CREATED, changeTypeCaptor.getValue()); Map<String, String> expectedDetail = new HashMap<>(); expectedDetail.put("extraDataName", "endpoint"); assertEquals(expectedDetail.toString(), detailCaptor.getValue()); } private MockMultipartFile createMockMultipartFile(String filename, String content) { byte[] contentBytes = content.getBytes(); return new MockMultipartFile("file", filename, null, contentBytes); } } ////////////////////////// class YourClassNameTest { @Mock private JoinPoint joinPoint; @Mock private FeatureExtraDataService featureExtraDataService; private YourClassName yourClass; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); yourClass = new YourClassName(featureExtraDataService); } @Test void testLogFeatureExtraDataDeleted_WhenSuccessIsTrue() { // Arrange int featureId = 1; String extraDataName = "extraData1"; boolean success = true; // Act yourClass.logFeatureExtraDataDeleted(joinPoint, featureId, extraDataName, success); // Assert ArgumentCaptor<Integer> featureIdCaptor = ArgumentCaptor.forClass(Integer.class); ArgumentCaptor<DataType> dataTypeCaptor = ArgumentCaptor.forClass(DataType.class); ArgumentCaptor<ChangeType> changeTypeCaptor = ArgumentCaptor.forClass(ChangeType.class); ArgumentCaptor<String> detailCaptor = ArgumentCaptor.forClass(String.class); verify(featureExtraDataService).saveChangeLog(featureIdCaptor.capture(), isNull(), dataTypeCaptor.capture(), changeTypeCaptor.capture(), detailCaptor.capture()); assertEquals(featureId, featureIdCaptor.getValue()); assertEquals(DataType.EXTRA_DATA, dataTypeCaptor.getValue()); assertEquals(ChangeType.DELETED, changeTypeCaptor.getValue()); Map<String, String> expectedDetail = new HashMap<>(); expectedDetail.put("extraDataName", extraDataName); assertEquals(expectedDetail.toString(), detailCaptor.getValue()); } @Test void testLogFeatureExtraDataDeleted_WhenSuccessIsFalse() { // Arrange int featureId = 2; String extraDataName = "extraData2"; boolean success = false; // Act yourClass.logFeatureExtraDataDeleted(joinPoint, featureId, extraDataName, success); // Assert verify(featureExtraDataService, Mockito.never()).saveChangeLog(anyInt(), any(), any(), any(), any()); } } /////////////////////////////////////////////////////////////////////////// Hàm get_sam_result_files() được sử dụng để tải xuống và trích xuất các file kết quả từ một tệp nén (zip file). Dưới đây là phân tích chi tiết của hàm này: Hàm bắt đầu bằng việc lấy URL tải xuống của artifact (tệp nén) từ GitHub sử dụng github_utils.get_artifact_download_url(): python Copier download_url = github_utils.get_artifact_download_url(env.GITHUB_TOKEN, env.REPOSITORY, env.RUN_ID, 'report_sam') env.GITHUB_TOKEN là mã thông báo (token) truy cập GitHub được sử dụng để xác thực yêu cầu API của GitHub. env.REPOSITORY là tên kho chứa (repository) GitHub. env.RUN_ID là ID của quá trình chạy (run) GitHub. 'report_sam' là tên của artifact (tệp nén) cần tải xuống. Sau đó, hàm kiểm tra xem có URL tải xuống được trả về hay không: python Copier if not download_url: return [] Nếu không có URL tải xuống được trả về, hàm trả về danh sách rỗng []. Tiếp theo, hàm tải xuống tệp nén từ URL sử dụng github_utils.download_artifact(): python Copier zip_file = github_utils.download_artifact(env.GITHUB_TOKEN, download_url) zip_file là một đối tượng đại diện cho tệp nén sau khi được tải xuống. Hàm kiểm tra xem có tệp nén được tải xuống thành công hay không: python Copier if not zip_file: return [] Nếu không có tệp nén được tải xuống thành công, hàm trả về danh sách rỗng []. Cuối cùng, hàm gọi hàm extract_zip(zip_file, 'html/') để trích xuất các file từ tệp nén với tiền tố 'html/': python Copier return extract_zip(zip_file, 'html/') Hàm extract_zip() được gọi với đối số zip_file là tệp nén đã tải xuống và prefix là 'html/'. Kết quả trả về từ extract_zip() là danh sách các file được trích xuất từ tệp nén, và hàm get_sam_result_files() trả về danh sách này. ///////////// Hàm update_sam_result(total_result) được sử dụng để cập nhật kết quả SAM (Software Assurance Marketplace) dựa trên dữ liệu tổng hợp được truyền vào. Dưới đây là phân tích chi tiết của hàm này: Hàm bắt đầu bằng việc gọi hàm upload_result_files(get_sam_result_files()). Điều này đặt mục tiêu là tải lên các file kết quả từ SAM bằng cách sử dụng hàm upload_result_files() và lấy danh sách các file kết quả từ hàm get_sam_result_files(). Mã trong hàm này không được cung cấp, vì vậy chúng ta không thể cung cấp thông tin chi tiết về cách hàm này hoạt động. Tiếp theo, hàm gọi upload_badge_to_s3('TOTAL', float(total_result['project_data']['score2'])). Điều này có mục tiêu là tải lên một biểu tượng (badge) lên dịch vụ lưu trữ đám mây S3 (Amazon S3) với tên là 'TOTAL' và giá trị được truyền vào từ total_result['project_data']['score2']. Giá trị này được ép kiểu thành số thực (float) trước khi truyền vào hàm upload_badge_to_s3(). Mã trong hàm này không được cung cấp, vì vậy chúng ta không thể cung cấp thông tin chi tiết về cách hàm này hoạt động. Tiếp theo, hàm có một vòng lặp for để duyệt qua các khóa trong total_result.keys(): python Copier for json_key in total_result.keys(): Trong vòng lặp, khối mã kiểm tra xem item (biến được tạo bằng cách loại bỏ _data từ json_key) có trong SAM_INDICATORS hay không: python Copier item = json_key.replace('_data', '') if item in SAM_INDICATORS: SAM_INDICATORS là một danh sách các chỉ số SAM. Nếu item thuộc SAM_INDICATORS, hàm gọi upload_badge_to_s3(item.upper(), float(total_result[json_key]['score'])). Điều này có mục tiêu tải lên một biểu tượng (badge) lên dịch vụ lưu trữ đám mây S3 với tên là item.upper() (chữ hoa) và giá trị được truyền vào từ total_result[json_key]['score']. Giá trị này được ép kiểu thành số thực (float) trước khi truyền vào hàm upload_badge_to_s3(). Mã trong hàm này không được cung cấp, vì vậy chúng ta không thể cung cấp thông tin chi tiết về cách hàm này hoạt động. Trong trường hợp xảy ra lỗi KeyError, hàm in ra thông báo "# unknown indicator : " cùng với json_key. Sau đó, vòng lặp tiếp tục với item tiếp theo bằng cách sử dụng lệnh continue. Điều này đảm bảo rằng nếu có một chỉ số không được nhận diện, thông báo sẽ được in ra và vòng lặp sẽ tiếp tục với item tiếp theo trong danh sách total_result.keys(). Thông qua hàm update_sam_result(total_result), các file kết quả từ SAM được tải lên và các biểu tượng (badges) tương ứng với các chỉ số SAM được tải lên dịch vụ lưu trữ đám mây S3. ///////// Hàm upload_result_files(files) được sử dụng để tải lên các file kết quả lên dịch vụ lưu trữ đám mây S3 (Amazon S3). Dưới đây là phân tích chi tiết của hàm này: Hàm bắt đầu bằng một vòng lặp for để duyệt qua danh sách các file được truyền vào: python Copier for file in files: Trong vòng lặp, hàm gọi aws_util.upload_binary() để tải lên một file nhị phân lên S3: python Copier aws_util.upload_binary(env.DEVOPS_TOOLS_BUCKET, 'sam/{}/{}'.format(TARGET_MODULE, file['path']), file['data'], content_type=file['mimetype']) aws_util là một module hoặc đối tượng cung cấp các chức năng để tương tác với dịch vụ AWS (Amazon Web Services). env.DEVOPS_TOOLS_BUCKET là tên của bucket (thùng) trong dịch vụ lưu trữ đám mây S3. 'sam/{}/{}'.format(TARGET_MODULE, file['path']) là đường dẫn đến vị trí mà file sẽ được lưu trữ trong S3. TARGET_MODULE là một biến hoặc giá trị được sử dụng để tạo đường dẫn. file['path'] là đường dẫn của file trong ổ đĩa cục bộ. file['data'] là dữ liệu của file nhị phân. content_type=file['mimetype'] là kiểu nội dung của file, được truyền thông qua tham số tùy chọn content_type. file['mimetype'] là kiểu MIME của file. Hàm upload_result_files() sẽ lặp qua danh sách các file và gọi hàm aws_util.upload_binary() để tải lên từng file lên dịch vụ lưu trữ đám mây S3. Chi tiết về cách hàm aws_util.upload_binary() hoạt động không được cung cấp trong đoạn mã này, vì vậy chúng ta không thể cung cấp thông tin chi tiết về cách hàm này thực hiện việc tải lên file lên S3. //////// Hàm upload_badge_to_s3(key, score) được sử dụng để tải lên một biểu tượng (badge) lên dịch vụ lưu trữ đám mây S3 (Amazon S3). Dưới đây là phân tích chi tiết của hàm này: Hàm bắt đầu bằng việc xác định màu sắc cho biểu tượng dựa trên score (điểm số) bằng cách gọi hàm get_badge_color(): python Copier color = get_badge_color(score) Tiếp theo, hàm xây dựng URL cho biểu tượng bằng cách sử dụng key (khóa) và score (điểm số) đã cho: python Copier badge_url = f'https://img.shields.io/badge/SAM%3A{key}-{score}-{color}.svg' Hàm in ra thông báo "# Downloading : " cùng với badge_url: python Copier print('# Downloading : ' + badge_url) Hàm gửi yêu cầu GET để tải xuống biểu tượng từ badge_url bằng cách sử dụng thư viện requests: python Copier response = requests.get(badge_url, stream=True) Kiểm tra xem yêu cầu có thành công không bằng cách kiểm tra response.ok. Nếu không thành công, hàm kết thúc chương trình bằng cách sử dụng sys.exit() và in ra thông báo lỗi: python Copier if not response.ok: sys.exit('response : ' + str(response)) Cuối cùng, hàm gọi aws_util.upload_binary() để tải lên nội dung của biểu tượng (badge) lên dịch vụ lưu trữ đám mây S3: python Copier aws_util.upload_binary(env.DEVOPS_TOOLS_BUCKET, 'sam/{}/{}.svg'.format(TARGET_MODULE, key), response.content, content_type='image/svg+xml') aws_util là một module hoặc đối tượng cung cấp các chức năng để tương tác với dịch vụ AWS (Amazon Web Services). env.DEVOPS_TOOLS_BUCKET là tên của bucket (thùng) trong dịch vụ lưu trữ đám mây S3. 'sam/{}/{}.svg'.format(TARGET_MODULE, key) là đường dẫn đến vị trí mà biểu tượng (badge) sẽ được lưu trữ trong S3. TARGET_MODULE là một biến hoặc giá trị được sử dụng để tạo đường dẫn. key là khóa của biểu tượng. response.content là nội dung của biểu tượng (badge) đã tải xuống từ badge_url. content_type='image/svg+xml' là kiểu nội dung của biểu tượng, được truyền thông qua tham số tùy chọn content_type. Trong trường hợp này, kiểu nội dung là "image/svg+xml" để chỉ định rằng biểu tượng là một file SVG (Scalable Vector Graphics). Hàm upload_badge_to_s3() tạo URL cho biểu tượng dựa trên key, score và màu sắc. Sau đó, nó tải xuống biểu tượng từ URL sử dụng requests và tải lên nội dung của biểu tượng lên S3 bằng cách sử dụng aws_util.upload_binary(). Chi tiết về cách các hàm get_badge_color() và aws_util.upload_binary() hoạt động không được cung cấp trong đoạn mã này, vì vậy chúng ta không thể cung cấp thông tin chitiết về cách các hàm này thực hiện công việc của mình.
Leave a Comment