[{"content":"When mega-sync fails with the following message:\nFailed to sync folder: Invalid argument. Unable to retrieve the ID of current device the problem is often not the sync path itself. In my case, the real issue was that the Ubuntu environment deployed inside Docker did not have a valid machine ID.\nWhy This Happens MEGA relies on the current device ID when creating or managing sync relationships. On some minimal Ubuntu container images, /etc/machine-id can be missing or empty. When that happens, mega-sync cannot identify the current device correctly and returns the misleading Invalid argument error.\nFix Generate a machine ID and write it to /etc/machine-id:\ndbus-uuidgen \u0026gt; /etc/machine-id After that, run the mega-sync command again. In this case, the sync operation should work normally.\nNotes This issue is commonly seen in Docker-based Ubuntu deployments. You may need root privileges to write to /etc/machine-id. If the file already exists, check whether it is empty before overwriting it. Reference The solution was based on the discussion in the MEGAcmd issue tracker:\nMEGAcmd issue #623 comment\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/mega-sync-invalid-device-id/","summary":"\u003cp\u003eWhen \u003ccode\u003emega-sync\u003c/code\u003e fails with the following message:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eFailed to sync folder: Invalid argument. Unable to retrieve the ID of current device\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003ethe problem is often not the sync path itself. In my case, the real issue was that the Ubuntu environment deployed inside Docker did not have a valid machine ID.\u003c/p\u003e\n\u003ch2 id=\"why-this-happens\"\u003eWhy This Happens\u003c/h2\u003e\n\u003cp\u003eMEGA relies on the current device ID when creating or managing sync relationships. On some minimal Ubuntu container images, \u003ccode\u003e/etc/machine-id\u003c/code\u003e can be missing or empty. When that happens, \u003ccode\u003emega-sync\u003c/code\u003e cannot identify the current device correctly and returns the misleading \u003ccode\u003eInvalid argument\u003c/code\u003e error.\u003c/p\u003e","title":"Fixing mega-sync \"Failed to sync folder: Invalid argument\" on Ubuntu Containers"},{"content":" A simple diagram showing how terms in the AI ​​field relate to each other\nSource and idea comes from: IBM\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/ai_venn/","summary":"\u003chr\u003e\n\u003cp\u003eA simple diagram showing how terms in the AI ​​field relate to each other\u003c/p\u003e\n\u003cp\u003eSource and idea comes from: \u003ca href=\"https://www.youtube.com/watch?v=qYNweeDHiyU\u0026amp;t=181s\"\u003eIBM\u003c/a\u003e\u003c/p\u003e","title":"AI Venn Diagram"},{"content":" This is some of my thinking about the Spring framework\u0026rsquo;s JDBC from my reverse engineering course. The location model image shows the abstract classes, implementation classes, interfaces, and methods that are directly or indirectly involved when executing the query method. The workflow image depicts the detailed function call process after initiating the JDBC query method.\nDue to space and time limitations, other branches resulting from polymorphism are not shown; only the chain produced by importing SQL of string type is displayed here.\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/springbootjdbc/","summary":"\u003chr\u003e\n\u003cblockquote\u003e\n\u003cp\u003eThis is some of my thinking about the Spring framework\u0026rsquo;s JDBC from my reverse engineering course. The \u003ccode\u003elocation model\u003c/code\u003e image shows the abstract classes, implementation classes, interfaces, and methods that are directly or indirectly involved when executing the query method. The \u003ccode\u003eworkflow\u003c/code\u003e image depicts the detailed function call process after initiating the JDBC query method.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003eDue to space and time limitations, other branches resulting from polymorphism are not shown; only the chain produced by importing SQL of string type is displayed here.\u003c/p\u003e","title":"SpringBoot JDBC Reverse Analysis"},{"content":"Warning message: WARN found no layout file for \u0026#34;html\u0026#34; for kind \u0026#34;home\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination. WARN found no layout file for \u0026#34;html\u0026#34; for kind \u0026#34;taxonomy\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination. WARN found no layout file for \u0026#34;html\u0026#34; for kind \u0026#34;section\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination. WARN found no layout file for \u0026#34;html\u0026#34; for kind \u0026#34;page\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination. WARN found no layout file for \u0026#34;html\u0026#34; for layout \u0026#34;archives\u0026#34; for kind \u0026#34;page\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination. WARN found no layout file for \u0026#34;html\u0026#34; for layout \u0026#34;search\u0026#34; for kind \u0026#34;page\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination. WARN found no layout file for \u0026#34;html\u0026#34; for kind \u0026#34;term\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination. WARN found no layout file for \u0026#34;json\u0026#34; for kind \u0026#34;home\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination. This will happen when you reclone repo with git submodule from remote branch and the submodule not get downloaded as well. In other words, Submodules may not get cloned automatically.\nSolution: git submodule init git submodule update Source\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/hugowarn/","summary":"\u003ch3 id=\"warning-message\"\u003eWarning message:\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eWARN  found no layout file for \u0026#34;html\u0026#34; for kind \u0026#34;home\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination.\nWARN  found no layout file for \u0026#34;html\u0026#34; for kind \u0026#34;taxonomy\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination.\nWARN  found no layout file for \u0026#34;html\u0026#34; for kind \u0026#34;section\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination.\nWARN  found no layout file for \u0026#34;html\u0026#34; for kind \u0026#34;page\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination.\nWARN  found no layout file for \u0026#34;html\u0026#34; for layout \u0026#34;archives\u0026#34; for kind \u0026#34;page\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination.\nWARN  found no layout file for \u0026#34;html\u0026#34; for layout \u0026#34;search\u0026#34; for kind \u0026#34;page\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination.\nWARN  found no layout file for \u0026#34;html\u0026#34; for kind \u0026#34;term\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination.\nWARN  found no layout file for \u0026#34;json\u0026#34; for kind \u0026#34;home\u0026#34;: You should create a template file which matches Hugo Layouts Lookup Rules for this combination.\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThis will happen when you reclone repo with git submodule from remote branch and the \u003ccode\u003esubmodule\u003c/code\u003e not get downloaded as well. In other words, Submodules may not get cloned automatically.\u003c/p\u003e","title":"Hugo Warning [found no layout file for ..]"},{"content":" Bucket Bucket Bucket\nStandard Classes S3 Standard - General Purpose 99.99% avaliability Used for frequent accessed data Low latency and high throughput Usage: Big data analytics, mobile \u0026amp; gaming applications, content distribution\u0026hellip;\nStandard - Infrequent Access For data that is less frequently accessed, but requires rapud acess when needed Lower cost than S3 standard Intelligent Tiering Moves objects automatically between Access Tiers based on usage Usage: Unknown or changing access\nOne-Zone IA Work only in single AZ; data lost when AZ is destroyed 99.5% avaliabity Usage: Storing secondary backup copies of on-premise data, or data you can recreate\nGlacier Storage Classes Low-cost object storage meant for archiving / backup Pricing: price for storage + object retrieval cost Glacier Instant Retrieval Millisecond retrieval, great for data accessed once a quarter Minimunm storage duration of 90 days Glacier Flexible Retrieval Expedited (1 to 5 minutes) , Standar (3 to 5 hours), Bulk( 5 to 12 hours) -free Minimum storage duration of 90 days Glacier Deep Archive Standard(12 hours), Bulk(48 hours) Minimum storage duration of 180 days All bucket have 99.99999999999% durability\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/aws-s3-storage-class/","summary":"\u003cblockquote\u003e\n\u003cp\u003eBucket Bucket Bucket\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch1 id=\"standard-classes\"\u003eStandard Classes\u003c/h1\u003e\n\u003ch2 id=\"s3-standard---general-purpose\"\u003eS3 Standard - General Purpose\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e99.99% avaliability\u003c/li\u003e\n\u003cli\u003eUsed for frequent accessed data\u003c/li\u003e\n\u003cli\u003eLow latency and high throughput\u003c/li\u003e\n\u003c/ul\u003e\n\u003cblockquote\u003e\n\u003cp\u003eUsage: Big data analytics, mobile \u0026amp; gaming applications, content distribution\u0026hellip;\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"standard---infrequent-access\"\u003eStandard - Infrequent Access\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eFor data that is less frequently accessed, but requires rapud acess when needed\u003c/li\u003e\n\u003cli\u003eLower cost than S3 standard\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"intelligent-tiering\"\u003eIntelligent Tiering\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eMoves objects automatically between Access Tiers based on usage\u003c/li\u003e\n\u003c/ul\u003e\n\u003cblockquote\u003e\n\u003cp\u003eUsage: Unknown or changing access\u003c/p\u003e","title":"AWS S3 Storage Class"},{"content":"The above picture shows the classic 3 tier solution architecture in AWS manner.This solution well solves problems such as disaster recovery, failover, load balancing, and network domain separation.\nBelow is the detailed description of tools using in the solution.\nRoute 53: Amazon Route 53 is a highly available and scalable Domain Name System (DNS) web service. It has health check abilitiy and failover solution. By using Route 53, you can fine-tune the DNS route with continuously high avaliablilty.\nELB: Elastic load balancer, including application load balancer, network load balancer and gateway load balancer. Just like its name， load balancer mainly focus on load balancing, it will dynamically allocate the server load based on your settting. They also have health check function which will automatically failover when server down.\nAuto Scalling Group: An Auto Scaling group contains a collection of EC2 instances that are treated as a logical grouping for the purposes of automatic scaling and management. Auto scalling group can sacle in and scale out between minimum and maximum capacity based on needs. Besides, they have abilty to terminate the unheathy instance and boot a new one automatically.\nM5: One of the instance type in AWS EC2\nElastic Cache: An memory based database which will store the data based on policy(TTL, write through,Lazy loading). When Cache hit, the server will retrieve data directly from cache,which greatly improving retrieval speed.\nRDS: AWS relational database service, with some cool features like read replica and multi AZ, which will maintain high speeed and avaliablity.\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/aws-3-tier-arch/","summary":"\u003cp\u003eThe above picture shows the classic 3 tier solution architecture in AWS manner.This solution well solves problems such as disaster recovery, failover, load balancing, and network domain separation.\u003c/p\u003e\n\u003cp\u003eBelow is the detailed description of tools using in the solution.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eRoute 53:  Amazon Route 53 is a highly available and scalable Domain Name System (DNS) web service. It has health check abilitiy and failover solution. By using Route 53, you can fine-tune the DNS route with continuously high avaliablilty.\u003c/p\u003e","title":"AWS Typical 3 Tier Solution Architecture"},{"content":"Static Analyzers Static analysis tools are essential in software development, focusing on improving code quality, identifying bugs, and ensuring adherence to coding standards without executing the code. They serve multiple purposes:\nCode Quality: Enhance code readability, maintainability, and efficiency.\nBug Detection: Identify and fix errors early in the development process.\nSecurity: Detect potential security vulnerabilities.\nPerformance: Highlight inefficient code patterns for optimization. These tools are used throughout the development lifecycle, particularly in:\nDevelopment: Integrated into IDEs, they provide real-time feedback to developers.\nCode Review: Automate the detection of potential issues before peer review.\nContinuous Integration: Included in CI pipelines to enforce code quality standards.\nCompliance: Ensure code adheres to industry-specific standards.\nTools like Checkstyle, PMD, and SonarQube are popular choices, each offering unique features to aid developers in creating robust, efficient, and secure Java applications.\nSpring boot: CheckStyle and PMD Both CheckStyle and PMD are easy to install in IDEA plugin. You can also integrate it inside the dependency through Gradle, I try to add the Spotbugs into Gradle at first, but it does not function and cause horrible issue. Then I give up and turn to CheckStyle and PMD.\nDue to the limitation of the plugin, We use SampleActuatorApplication.java in actuator smoke as a single control group for testing. Here is the result:\nI don\u0026rsquo;t know why it automatically generates the chinese output, it did convent for me but also make more work for me. You can see in the rules section on the left right corner we use google checks, we have two default configurations, one is call Sun checks, I choose google checks since sun checks generate a more horrible result than Google, but a Google result is not very good either. I\u0026rsquo;ll talk about it later.\nLet\u0026rsquo;s take a look at how PMD performance. PMD plugin supports multi file scan, and I ask it to check some test system. And only 10 files generate 67 violations. Its shocking result, but let\u0026rsquo;s see what really happen.\nLet\u0026rsquo;s go back to the Check style: On the highlight text it said: \u0026lsquo;method def modifier\u0026rsquo; indent 8 and should be 2. The above line says： there is tab in line. Both problem happen in line 36, lets see what line 36 do.\nThis is line 36 in SampleActuatorApplication class, we can see this is a @Bean annotation, which is a spring boot characteristic. It\u0026rsquo;s clear that the default Checkstyle configuration cannot identify the annotation and treat this as an unexpected indentation. Let\u0026rsquo;s see how PMP did.\nSimilarly, PMP doesn\u0026rsquo;t perform very well in default, in line 34, it said it should declare at least one constructor, but actually, spring boot will automatically offer a default constructor when there is no explicit constructor exist.\nHence, both static analyzers may not function well without specific configuration. And nowadays, we did have a very powerful static analyzer call IDEA.\nCheck Overlap Some functions both static analyzers provided are similar, for example, the code style. In PMD, its located in the documentation section and comment size: The document section is ask you to add some comments on the class and constructor, and the comment size will inform you when the comment is too large. I do not see the overlap appear. In summary, the checkStyle is focusing on the formatting only, but the PMD is mainly used to find potential problems in the code, such as complex code that may cause errors, unused parameters or variables, overly complex expressions, etc. It focuses more on the logical and structural quality of the code. However, without targeted configuration, both plugins are far from the level that can be deployed in a production environment.\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/springboottest6/","summary":"\u003ch1 id=\"static-analyzers\"\u003eStatic Analyzers\u003c/h1\u003e\n\u003cp\u003eStatic analysis tools are essential in software development, focusing on improving code quality, identifying bugs, and ensuring adherence to coding standards without executing the code. They serve multiple purposes:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003eCode Quality: Enhance code readability, maintainability, and efficiency.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eBug Detection: Identify and fix errors early in the development process.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eSecurity: Detect potential security vulnerabilities.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ePerformance: Highlight inefficient code patterns for optimization.\nThese tools are used throughout the development lifecycle, particularly in:\u003c/p\u003e","title":"Spring Boot Software Testing 6 - Static Analyzers"},{"content":"Testable Design and Mocking What is testable design, and what kinds of design in java are testable?\nIn Java, achieving a testable design is about adhering to principles and practices that minimize coupling, maximize cohesion, and facilitate isolation of components for testing. It involves strategic use of design patterns, architectural decisions that favor testability, and leveraging tools and frameworks that support automated testing. This approach not only makes your code more testable but also improves its overall design and maintainability.\nDummy code in Spring boot Unfortunately, finding a code that is hard to test is nearly impossible in Spring Boot.In other words, Spring Boot is a near perfect project(in testable level), which is in line with its dominant position in the java framework system.\nHere is the reason why hard-to-test code hardly exists in Spring Boot:\n1. Spring DI IOC container One of the major features of spring boot is the extensive use of Java reflection for dependency injection and inversion of control. This is the core of spring framework.Dependency injection makes it easy to replace actual dependencies in a test environment, using a simplified implementation or an instance created specifically for testing purposes.\n2. full application context @SpringBootTest Spring provides a powerful test context framework that supports test configuration classes and test data management. Besides, Spring Boot provides rich testing support, including annotations and tools for unit testing and integration testing, such as @SpringBootTest, @DataJpaTest, @WebMvcTest, etc. These tools and annotations simplify the setup of test environments, allowing developers to quickly write and execute tests, whether for a specific layer (such as the web layer, service layer, or persistence layer) or for the entire application.\n3. AutoConfiguration Different from a traditional Spring framework, Spring Boot uses autoconfigure to ensures the consistency and correctness of configuration. In a test environment, this means that the same auto-configuration principles can be used to set up the test environment, reducing testing problems caused by improperly configured test environments.\n4. Environment Abstractions Spring Boot provides a variety of environment abstractions, such as configuration files and configuration classes, allowing developers to flexibly configure applications according to the running environment (development, testing, production, etc.). These abstractions also apply to the test environment, making it easy to adjust the configuration of the test environment (such as database connections, external services, etc.) and avoid hardcoding these settings.\nIn summary, I think it is extremely difficult for dummy code to exist in the spring boot repo; mostly it will be rejected by the pull request peer review; And it will be short-term existence even if it does appear.\nMocking Mocking is a technique used in unit testing to simulate the behavior of real objects in a controlled way. It allows developers to isolate the unit of code they are testing by replacing its dependencies with mock objects. These mock objects can mimic the behavior of complex, real-world dependencies such as databases, web services, or other external systems without the overhead of setting up actual connections or state. Mocking is particularly useful in situations where the real dependencies are unreliable, slow, or difficult to configure for testing purposes.\nMocking is typically achieved using specialized libraries or frameworks designed for this purpose. Some popular mocking frameworks in the Java ecosystem include Mockito, JMock, and EasyMock. These frameworks provide annotations and APIs to create mock objects, define their behavior (e.g., specifying what values they should return when certain methods are called), and verify that they were interacted with in expected ways.\nSpring Boot In the process of observing spring boot testing, I found that spring boot rarely uses mocking to test their components. In spring boot philosophy, they tend to make the testing more simply. Spring Boot encourages testing with real components to ensure that parts of the application work together as expected. According to my rough statistics, only 1% of the code uses mockito, and most of this is intentional.\nI made two test cases in spring boot actuator smoke test here is the detailed case:\nThe first case use the build-in mock call mockMvc, the other one is traditional mockito.\nThe first one is preferred in a current scenario. The mockito one is runnable but not recommended.\nMockMvc provides a powerful API that allows you to simulate HTTP requests and responses in order to test the behavior of the web layer without starting a full HTTP server. Mockito is more used for general unit testing, especially when you need to simulate class or method behavior.\nThe first one interacts directly with the spring boot controller, constructs an http request, and verifies the response status code\nThe second one created a fictional ResponseEntity and mock the RestTemplate, the MockResponseEntity will return when specific url get call. The ResponseEnitity will return a small string that is some of the expected data and a http status code. However, this method has limitations because it does not actually construct an http request and call the actuator component, and may not reflect the real situation when the system is deployed.\nBoth tests passed.\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/springboottest5/","summary":"\u003ch1 id=\"testable-design-and-mocking\"\u003eTestable Design and Mocking\u003c/h1\u003e\n\u003chr\u003e\n\u003cp\u003eWhat is testable design, and what kinds of design in java are testable?\u003c/p\u003e\n\u003cp\u003eIn Java, achieving a testable design is about adhering to principles and practices that minimize coupling, maximize cohesion, and facilitate isolation of components for testing. It involves strategic use of design patterns, architectural decisions that favor testability, and leveraging tools and frameworks that support automated testing. This approach not only makes your code more testable but also improves its overall design and maintainability.\u003c/p\u003e","title":"Spring Boot Software Testing 5 - Testable Design and Mocking"},{"content":"Continuous Integration Continuous Integration (CI) is a software development practice where developers frequently merge their code changes into a central repository, preferably multiple times a day. Each merge triggers an automated build and testing process, which helps in identifying and addressing integration errors as quickly as possible. The primary purpose of CI is to improve software quality and accelerate the development process.\nKey aspects of Continuous Integration include:\nAutomated Building and Testing: Automated tools are used to compile the code and run tests every time changes are integrated. This ensures that the software is always in a state where it can be deployed.\nVersion Control Integration: CI relies heavily on version control systems to manage changes to the codebase. Developers are encouraged to commit changes frequently, which supports the detection of conflicts and integration issues early in the development cycle.\nImmediate Feedback: Developers receive immediate feedback on their commits. If a build or test fails, the system alerts the responsible developers so they can fix the issue promptly. This reduces the debugging time later in the development cycle.\nConsistency: The use of automated tools ensures that builds and tests are executed in a consistent environment. This minimizes the \u0026ldquo;it works on my machine\u0026rdquo; syndrome, where code behaves differently on different developers\u0026rsquo; environments.\nEfficiency: Automated tests and builds reduce the manual work required from developers, allowing them to focus on writing code. This efficiency can lead to faster development cycles and quicker time to market.\nThe purpose of Continuous Integration is to:\nDetect and address integration issues early: By integrating frequently, issues can be identified and resolved early in the development process, reducing the complexity of fixing bugs.\nImprove software quality: Regular testing ensures that defects are caught and corrected early, improving the overall quality of the software.\nReduce time to market: Efficient processes and early detection of issues lead to shorter development cycles, enabling faster release of products.\nEnhance project visibility and feedback: Continuous Integration provides a clear insight into the project\u0026rsquo;s health through the status of builds and tests, making it easier to assess progress.\nOverall, Continuous Integration is a critical component of modern software development practices, particularly in agile environments. It supports the development of high-quality software while enabling teams to be more productive and responsive to changes.\nSpring boot Spring boot itself has its own continuous integration located in GitHub Actions. The specific configuration is written like this:\nname: Build Pull Request on: pull_request permissions: contents: read jobs: build: name: Build pull request runs-on: ubuntu22-8-32 if: ${{ github.repository == \u0026#39;spring-projects/spring-boot\u0026#39; }} steps: - name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: \u0026#39;17\u0026#39; distribution: \u0026#39;liberica\u0026#39; - name: Check out code uses: actions/checkout@v4 - name: Validate Gradle wrapper uses: gradle/wrapper-validation-action@699bb18358f12c5b78b37bb0111d3a0e2276e0e2 - name: Set up Gradle uses: gradle/gradle-build-action@3b1b3b9a2104c2b47fbae53f3938079c00c9bb87 - name: Build env: CI: \u0026#39;true\u0026#39; GRADLE_ENTERPRISE_URL: \u0026#39;https://ge.spring.io\u0026#39; run: ./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --no-parallel --continue build - name: Print JVM thread dumps when cancelled uses: ./.github/actions/print-jvm-thread-dumps if: cancelled() - name: Upload build reports uses: actions/upload-artifact@v4 if: failure() with: name: build-reports path: \u0026#39;**/build/reports/\u0026#39; However, if not make any changes, it will be automatically skip rather than triggered.\nThree places modified to make sure the action builds trigger. The first one changes the trigger type, from pull request to commit. The second one changes the repo location. And the last one makes an adjustment on system type to make it match GitHub Action\u0026rsquo;s environment identifier.\nLet\u0026rsquo;s make a push to see if github actions working properly.\nAfter 50 minutes wait, the build action gets successfully triggered, but the build failed. We get not log file except one annotation:\nBuild commit The hosted runner: GitHub Actions 7 lost communication with the server. Anything in your workflow that terminates the runner process, starves it for CPU/Memory, or blocks its network access can cause this error.\nGitHub action unexpectedly lost the connection to the server.Based on its prompt, I speculate the system crashes due to out of memory . Spring boot is so huge that an average performance server is unable to handle this task. I checked peers build time. On average, it only takes 5 to 10 minutes to complete the build on one platform, maximum no over 15min.\nFortunately, We made a pull request in the previous coverage test, which gave us a chance to call the build system of the main repository, we can see what\u0026rsquo;s going on inside.\nIn the right conor of the panel, we can clearly see that even with a well-tuned server, it still took 24 minutes to complete the build.Furthermore, a total of five thousand lines were recorded in the log. In line 3123, we can notice that as a widely used framework, spring boot has strict content review standards. The red block is the cause of the build failure, which is caused by my introduced code. Springboot\u0026rsquo;s build configuration introduces format detection, which they call check-style, and uses this to normalize all code blocks. You will see that I just miss one space after a comma, a whole build failure. I adjusted this and committed to the remote repo again.\nYou can see that after the new commit new build finishes successfully.Below are excution details.\nYou can see it consume 29 minutes to finish the build. All the tasks in the screenshot are related to spring boot actuator smoke test.I speculate all the changes I made are tested by the task on line 3189, and the other tasks are some system-level tests.\nSpring boot\u0026rsquo;s CI tool is characterized for long building time, and its complex dependencies are the main contributor. Even so, we still see that the spring boot project team is still actively performing frequent build tests. As I write this assignment, the spring boot panel shows that new builds are still in progress. I think this is one of the reasons for the success of spring boot\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/springboottest4/","summary":"\u003ch1 id=\"continuous-integration\"\u003eContinuous Integration\u003c/h1\u003e\n\u003cp\u003eContinuous Integration (CI) is a software development practice where developers frequently merge their code changes into a central repository, preferably multiple times a day. Each merge triggers an automated build and testing process, which helps in identifying and addressing integration errors as quickly as possible. The primary purpose of CI is to improve software quality and accelerate the development process.\u003c/p\u003e\n\u003cp\u003eKey aspects of Continuous Integration include:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eAutomated Building and Testing\u003c/strong\u003e: Automated tools are used to compile the code and run tests every time changes are integrated. This ensures that the software is always in a state where it can be deployed.\u003c/p\u003e","title":"Spring Boot Software Testing 4 - Continuous Integration"},{"content":"White Box Testing and Coverage Structural testing, often referred to as white-box testing, is a rigorous methodology for evaluating the internal workings of a software application. This technique delves into the application\u0026rsquo;s source code, architecture, and design, offering a detailed view of its internal pathways. Unlike black-box testing, which assesses the software\u0026rsquo;s external functionality without regard to its internal mechanisms, structural testing demands an intimate understanding of the codebase. This approach allows testers to meticulously examine execution paths, logic flows, and the outcomes of various code segments.\nThe Crucial Role of Structural Testing Enhanced Code Coverage: One of the paramount benefits of structural testing is its ability to achieve exhaustive code coverage. It meticulously examines branches, loops, and individual statements within the code, ensuring that no part is left untested. This level of scrutiny is vital for uncovering errors that might elude functional testing, thereby bolstering the software\u0026rsquo;s reliability and performance.\nDetection of Concealed Bugs: Structural testing shines in its ability to unearth bugs that lurk beneath the surface, invisible to more superficial testing methodologies. It probes into the software\u0026rsquo;s inner mechanisms, identifying edge cases and unique conditions that might otherwise remain undiscovered until after deployment.\nStreamlined Debugging Process: The intimate association between structural testing and the application\u0026rsquo;s codebase significantly eases the debugging process. When a test fails, developers can quickly pinpoint the exact location of the fault within the code, facilitating a more efficient and targeted debugging effort.\nElevated Software Quality: By verifying that the code behaves as intended across a wide array of scenarios and inputs, structural testing contributes significantly to enhancing the software\u0026rsquo;s overall quality. This comprehensive examination helps ensure a superior user experience and can substantially reduce the need for future maintenance and bug fixes.\nSupport for Refactoring and Integration: Structural testing is invaluable during code refactoring and the integration of new features. It provides a safety net that ensures modifications do not introduce new errors, allowing the software to evolve while maintaining its integrity and functionality.\nBolstering Security: Given its thorough exploration of code pathways, structural testing plays a key role in identifying potential security vulnerabilities. This is crucial for applications dealing with sensitive information or those that are integral to business operations, as it helps prevent exploitations that could lead to data breaches or other security incidents.\nCompliance with Regulatory Standards: In certain industries, achieving comprehensive code coverage through structural testing is not just beneficial but mandated. This ensures that software adheres to rigorous quality and safety standards, an essential requirement in sectors where software reliability is paramount.\nTo sum up, structural testing is indispensable for ensuring that software is not only functional but also robust, secure, and of high quality. It complements functional testing by offering a deep dive into the software\u0026rsquo;s internal mechanics, thereby playing a critical role in the development of reliable, efficient, and secure applications.\nImplementation Our test case mainly focuses on method coverage,but also improves some line coverage and branch coverage rate.\nWith the help of IDEA coverage tool, we quickly found some targets. They are:\nBoth method are relatively simple, the first one handles HTTP POST requests to the root URL (\u0026quot;/\u0026quot;) and return some kinds of map info such as current date etc., and the second one is mapping a KV pair into the end of actuator info.\nChallenges Encountered Our initial attempts to cover the first target with test cases resulted in multiple failures. Specifically, we encountered a 401 Unauthorized status instead of the expected 200 OK. Upon reviewing the debug logs, we discovered that Spring Security\u0026rsquo;s CSRF (Cross-site request forgery) protection was blocking the POST requests.\nDespite disabling CSRF protection, our tests still returned a 404 status, indicating further complications possibly related to requiring a valid token or additional configuration adjustments.\nGiven the complexity of Spring Security and our limited experience with it, we decided to redirect our efforts towards other methods for coverage improvement. Spring Security\u0026rsquo;s comprehensive nature suggested that a deeper dive into its configuration and security mechanisms would be necessary for successful method coverage in areas protected by security policies.\nWe turn our attention to the second method. It seems like this code is brief, but in fact it does a lot of things under the hood. You may notice that the method itself introduce a new Builder class. See the below picture to take a look at this class itself.\nLet\u0026rsquo;s analyze what this code does specifically from the source code perspective.\nInterface Implementation: It overrides the InfoContributor interface\u0026rsquo;s contribute method. Implementing this interface enables the addition of custom information to the Actuator\u0026rsquo;s /info endpoint through the introduction of a Builder class.\nDetail Addition: Utilizes the Builder class\u0026rsquo;s withDetail method to add a key-value pair (example key with a map object {someKey, someValue}) as custom information.\nHashMap Initialization and Construction: The Builder initializes and constructs a new HashMap, incorporating existing info content. This step ensures that any previously available information is retained and integrated with the new details.\nInfo Map Construction: It calls the withDetail method again to incorporate the custom information into the new HashMap, effectively building the enriched info map.\nInfo Map Retrieval: Upon request to the /info endpoint, the method returns the newly constructed info map, now containing both existing and newly added details.\nTest case The test case aims to verify the functionality of the override contribute method within the Spring Boot Actuator\u0026rsquo;s info endpoint. It focuses on ensuring that:\nThe HTTP connection is successfully established. The info endpoint is correctly configured and returns the expected build key. The contribute method functions as intended, allowing for custom information to be added to the endpoint. @Test @SuppressWarnings(\u0026#34;unchecked\u0026#34;) void testInfo() { ResponseEntity\u0026lt;Map\u0026lt;String, Object\u0026gt;\u0026gt; entity = asMapEntity( this.restTemplate.withBasicAuth(\u0026#34;user\u0026#34;, \u0026#34;password\u0026#34;).getForEntity(\u0026#34;/actuator/info\u0026#34;, Map.class)); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(entity.getBody()).containsKey(\u0026#34;build\u0026#34;); Map\u0026lt;String, Object\u0026gt; body = entity.getBody(); Map\u0026lt;String, Object\u0026gt; example = (Map\u0026lt;String, Object\u0026gt;) body.get(\u0026#34;example\u0026#34;); assertThat(example).containsEntry(\u0026#34;someKey\u0026#34;, \u0026#34;someValue\u0026#34;); } Assertions HTTP Status Check: Validates that the HTTP connection to the info endpoint is established, indicated by an HttpStatus.OK response. build Key Existence: Confirms that the info endpoint is functioning correctly by checking for the presence of the build key, a critical component of the endpoint\u0026rsquo;s response. contribute Method Functionality: Verifies that the contribute method properly adds custom information (\u0026ldquo;someKey\u0026rdquo;: \u0026ldquo;someValue\u0026rdquo;) to the endpoint\u0026rsquo;s response. These are the coverage output after this tested case added. You can clearly see the changes in coverage methods, lines and branches. After incorporating this test case, the coverage metrics showed significant improvements in methods, lines, and branches within the tested class. However, to further enhance coverage, especially for untested branches and methods in the info class, additional tests could be considered. These might include:\nTesting the equal method with various expected outcomes. Calling the get method with both valid and invalid types. Such tests would delve deeper into the framework\u0026rsquo;s internal functionality rather than focusing solely on the actuator smoke test system.\nConclusion This test case effectively enhances the test coverage of the Spring Boot Actuator\u0026rsquo;s info endpoint, particularly focusing on the contribute method\u0026rsquo;s functionality. For comprehensive coverage, further tests exploring additional branches and methods within the info class are recommended.\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/springboottest3/","summary":"\u003ch1 id=\"white-box-testing-and-coverage\"\u003eWhite Box Testing and Coverage\u003c/h1\u003e\n\u003cp\u003eStructural testing, often referred to as white-box testing, is a rigorous methodology for evaluating the internal workings of a software application. This technique delves into the application\u0026rsquo;s source code, architecture, and design, offering a detailed view of its internal pathways. Unlike black-box testing, which assesses the software\u0026rsquo;s external functionality without regard to its internal mechanisms, structural testing demands an intimate understanding of the codebase. This approach allows testers to meticulously examine execution paths, logic flows, and the outcomes of various code segments.\u003c/p\u003e","title":"Spring Boot Software Testing 3 - White Box Testing and Coverage"},{"content":"Finite State machine Finite models are essential in testing for simplifying complex systems, allowing exhaustive testing, and facilitating automated test case generation. They offer a clear way to represent systems as finite state machines, making it possible to explore all possible states and transitions. This approach is critical for ensuring systems behave as expected under every scenario, especially in critical applications where failure is unacceptable.\nKey benefits include:\nSimplification: Reducing complex systems to manageable models. Exhaustive Testing: Enabling complete coverage of all possible states and transitions. Automated Testing: Supporting the generation of test cases and regression testing. Formal Verification: Allowing mathematical proofs of system correctness through model checking and other formal methods. Finite models are widely used in software and hardware testing to improve test coverage, find potential issues, and ensure system reliability. However, challenges such as scalability and the accuracy of the models must be managed to ensure effective testing outcomes.\nSrping boot actuator Spring boot actuator is one of the most important component from spring boot.provides a set of ready-to-use features to help you monitor and manage your application. These features allow you to inspect the internal state of your application, such as health status, metrics, environment information, and more. This is especially useful for microservices architectures in production environments.\nThere are some endpoints from actuator:\n/actuator: The root endpoint that lists all available actuator endpoints. /health: Summarizes the health status of your application. /heapdump: Triggers a dump of the Java heap. /httptrace: Shows HTTP trace information (by default, the last 100 HTTP request-response exchanges). /info: Displays arbitrary application info. /loggers: Enables viewing and modifying the logging level of application loggers. /metrics: Shows ‘metrics’ information for the current application. /shutdown: Lets you gracefully shut down the application (disabled by default). /env: Exposes properties from Spring’s ConfigurableEnvironment. This is the function what actuator offers; I won’t explain the detailed functions here. The spring boot basic policy is: All the function except /health will be treated as sensitive data which will not open to the public until the auth passed.\nThe finite state machine without verification will be look like this:\nAll the actuator function except health will be received a http 302 redirect response. The health will be received http ok and show the data query.\nLet\u0026rsquo;s see how the finite state machine change when verification completed.\nNow, the server will make more response, not just including all the actuator services, but also the exception handling. like /foo will response http500. http 403 will pop up when make a GET request in prohibited port when CORS enable.\nBelow shows a bunch of screenshots about how it actually reacts:\nfirst the login page try to enter actuator/env and excute, page automatically fall back to login page try use actuator/health get the new return /actuator/env now functional after entering correct username and password try exception page, get http 500 try to get some page not existed, get http 404 login fail can also be a simple state machine, but it\u0026rsquo;s code implementation based on spring security, hence not within the scope of this discussion ","permalink":"https://c57b4987.mrwblog.pages.dev/posts/springboottest2/","summary":"\u003ch1 id=\"finite-state-machine\"\u003eFinite State machine\u003c/h1\u003e\n\u003cp\u003eFinite models are essential in testing for simplifying complex systems, allowing exhaustive testing, and facilitating automated test case generation. They offer a clear way to represent systems as finite state machines, making it possible to explore all possible states and transitions. This approach is critical for ensuring systems behave as expected under every scenario, especially in critical applications where failure is unacceptable.\u003c/p\u003e\n\u003cp\u003eKey benefits include:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eSimplification: Reducing complex systems to manageable models.\u003c/li\u003e\n\u003cli\u003eExhaustive Testing: Enabling complete coverage of all possible states and transitions.\u003c/li\u003e\n\u003cli\u003eAutomated Testing: Supporting the generation of test cases and regression testing.\u003c/li\u003e\n\u003cli\u003eFormal Verification: Allowing mathematical proofs of system correctness through model checking and other formal methods.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eFinite models are widely used in software and hardware testing to improve test coverage, find potential issues, and ensure system reliability. However, challenges such as scalability and the accuracy of the models must be managed to ensure effective testing outcomes.\u003c/p\u003e","title":"Spring Boot Software Testing 2 - Actuator - Finite State Machine"},{"content":"Spring Boot is a project under the Spring Framework that simplifies developing, configuring, and deploying Spring-based applications. It promotes convention over configuration by offering pre-configured setups and auto-configuration based on project dependencies, eliminating much of the manual setup and configuration work. Spring Boot applications are stand-alone, containing an embedded web server for easy deployment as a single executable JAR. It offers opinionated defaults to reduce development effort, while still allowing for customization. Features like Actuator provide built-in endpoints for application monitoring and management. Primarily written in Java, Spring Boot supports other JVM languages like Kotlin and Groovy, making it versatile for various enterprise applications. Its goal is to enable quick application startup with less code and configuration hassle.\nSpring is popular for its numerous advantages: It promotes testable code through its dependency injection method. Offers robust yet user-friendly database transaction management. Facilitates seamless integration with other Java frameworks such as JPA/Hibernate ORM and web frameworks like Struts/JSF. Provides a cutting-edge Web MVC framework for developing web applications. Spring boot size of LOC By using\nfind . -name \u0026#39;*.java\u0026#39; | xargs wc -l You can easily find the specific LOC of Spring boot project The result is 257187 total, I also find some data come from internet about the spring boot LOC in 2020, which you can check below.\nspring-boot-test : 13608 spring-boot-starters : 0 spring-boot-autoconfigure : 69450 spring-boot-docs : 1131 spring-boot-properties-migrator : 548 spring-boot-tools : 33627 spring-boot-cli : 10278 spring-boot-dependencies : 0 spring-boot-test-autoconfigure : 8439 spring-boot-actuator-autoconfigure : 26997 spring-boot-actuator : 27745 spring-boot-parent : 0 spring-boot-devtools : 10912 spring-boot : 61107 Total size of LOC：263842 Testing Spring Boot provides a comprehensive suite of components to facilitate testing for applications built with it. These components simplify the process of writing and executing tests by providing auto-configuration, utility classes, and annotations. Here\u0026rsquo;s an overview of some of the key testing components and features offered by Spring Boot:\n@SpringBootTest: This annotation is used for integration testing in Spring Boot applications. It loads the complete application context and is useful for testing the interaction between all parts of the application.\n@DataJpaTest: Specifically designed for testing JPA repositories, this annotation configures an in-memory database, scans for @Entity classes, and configures Spring Data JPA repositories. It\u0026rsquo;s ideal for data access layer testing.\n@WebMvcTest: It is used for testing MVC controllers without starting a full HTTP server. It auto-configures MockMvc for easy testing of controller endpoints.\n@WebFluxTest: Similar to @WebMvcTest, but for applications using Spring WebFlux. It helps in testing annotated controllers in a non-blocking way.\n@RestClientTest: This annotation is useful for testing REST clients. It auto-configures MockRestServiceServer to mock remote REST services.\n@MockBean and @SpyBean: Spring Boot provides these annotations for adding Mockito mocks or spies into the Spring application context. They can be used to replace or spy on beans in the context for unit testing.\nTestRestTemplate and WebTestClient: For integration testing, Spring Boot offers TestRestTemplate for RESTful communication and WebTestClient for testing reactive web applications, making it easier to test web layers.\nJsonPath and XmlPath: For testing RESTful services, Spring Boot supports JsonPath and XmlPath to query and assert the JSON or XML response content.\nAuto-configured Test Databases: Spring Boot can automatically configure an in-memory database for tests, such as H2, which is very convenient for testing data access layers without the need for a real database.\n@TestConfiguration: This annotation helps to define additional beans or customizations for the test context. It allows overriding of certain parts of the application configuration only for tests.\nThese components, among others, provide a robust framework for both unit and integration testing in Spring Boot applications, ensuring that developers can write comprehensive tests with minimal boilerplate code.\nTest cases The spring boot project itself uses a large number of test cases to ensure that all components serve as expected. The following shows the directory structure under the spring boot test folder.\n. ├── spring-boot-integration-tests │ ├── spring-boot-configuration-processor-tests │ ├── spring-boot-launch-script-tests │ ├── spring-boot-loader-classic-tests │ ├── spring-boot-loader-tests │ └── spring-boot-server-tests └── spring-boot-smoke-tests ├── spring-boot-smoke-test-activemq ├── spring-boot-smoke-test-actuator ├── spring-boot-smoke-test-actuator-custom-security ├── spring-boot-smoke-test-actuator-log4j2 ├── spring-boot-smoke-test-actuator-noweb ├── spring-boot-smoke-test-actuator-ui ├── spring-boot-smoke-test-amqp ├── spring-boot-smoke-test-ant ├── spring-boot-smoke-test-aop ├── spring-boot-smoke-test-batch ├── spring-boot-smoke-test-bootstrap-registry ├── spring-boot-smoke-test-cache ├── spring-boot-smoke-test-data-cassandra ├── spring-boot-smoke-test-data-couchbase ├── spring-boot-smoke-test-data-jdbc ├── spring-boot-smoke-test-data-jpa ├── spring-boot-smoke-test-data-ldap ├── spring-boot-smoke-test-data-mongo ├── spring-boot-smoke-test-data-r2dbc ├── spring-boot-smoke-test-data-r2dbc-flyway ├── spring-boot-smoke-test-data-r2dbc-liquibase ├── spring-boot-smoke-test-data-redis ├── spring-boot-smoke-test-data-rest ├── spring-boot-smoke-test-devtools ├── spring-boot-smoke-test-flyway ├── spring-boot-smoke-test-graphql ├── spring-boot-smoke-test-hateoas ├── spring-boot-smoke-test-integration ├── spring-boot-smoke-test-jersey ├── spring-boot-smoke-test-jetty ├── spring-boot-smoke-test-jetty-jsp ├── spring-boot-smoke-test-jetty-ssl ├── spring-boot-smoke-test-jpa ├── spring-boot-smoke-test-junit-vintage ├── spring-boot-smoke-test-kafka ├── spring-boot-smoke-test-liquibase ├── spring-boot-smoke-test-logback ├── spring-boot-smoke-test-oauth2-authorization-server ├── spring-boot-smoke-test-oauth2-client ├── spring-boot-smoke-test-oauth2-resource-server ├── spring-boot-smoke-test-parent-context ├── spring-boot-smoke-test-profile ├── spring-boot-smoke-test-property-validation ├── spring-boot-smoke-test-pulsar ├── spring-boot-smoke-test-quartz ├── spring-boot-smoke-test-reactive-oauth2-client ├── spring-boot-smoke-test-reactive-oauth2-resource-server ├── spring-boot-smoke-test-rsocket ├── spring-boot-smoke-test-saml2-service-provider ├── spring-boot-smoke-test-secure ├── spring-boot-smoke-test-secure-jersey ├── spring-boot-smoke-test-secure-webflux ├── spring-boot-smoke-test-servlet ├── spring-boot-smoke-test-session-hazelcast ├── spring-boot-smoke-test-session-jdbc ├── spring-boot-smoke-test-session-mongo ├── spring-boot-smoke-test-session-redis ├── spring-boot-smoke-test-session-webflux-mongo ├── spring-boot-smoke-test-session-webflux-redis ├── spring-boot-smoke-test-simple ├── spring-boot-smoke-test-test ├── spring-boot-smoke-test-test-nomockito ├── spring-boot-smoke-test-testng ├── spring-boot-smoke-test-tomcat ├── spring-boot-smoke-test-tomcat-jsp ├── spring-boot-smoke-test-tomcat-multi-connectors ├── spring-boot-smoke-test-tomcat-ssl ├── spring-boot-smoke-test-traditional ├── spring-boot-smoke-test-undertow ├── spring-boot-smoke-test-undertow-ssl ├── spring-boot-smoke-test-war ├── spring-boot-smoke-test-web-application-type ├── spring-boot-smoke-test-web-freemarker ├── spring-boot-smoke-test-web-groovy-templates ├── spring-boot-smoke-test-web-jsp ├── spring-boot-smoke-test-web-method-security ├── spring-boot-smoke-test-web-mustache ├── spring-boot-smoke-test-web-secure ├── spring-boot-smoke-test-web-secure-custom ├── spring-boot-smoke-test-web-secure-jdbc ├── spring-boot-smoke-test-web-static ├── spring-boot-smoke-test-web-thymeleaf ├── spring-boot-smoke-test-webflux ├── spring-boot-smoke-test-webflux-coroutines ├── spring-boot-smoke-test-webservices ├── spring-boot-smoke-test-websocket-jetty ├── spring-boot-smoke-test-websocket-tomcat ├── spring-boot-smoke-test-websocket-undertow └── spring-boot-smoke-test-xml Smoke test is an industry testing specification. It is responsible for basic functional testing to ensure that basic functions and processes can work. If and only if the smoke test passes, more detailed tests such as functional testing, integration testing, system testing, etc. will begin, so the smoke test is a good entry point for testing. You can find that spring boot not only tests its own developed components such as actuator, but also conducts detailed tests on other inherited components.We can find some familiar figures in it， like kafka, redis, log4j2 etc.\nRunning the test case Spring boot uses gradle as its automated build tool. To test the entire project, you can simply run:\ngradle clean test Gradle will automatically compile the project and test all existing and not ignored test cases.\nBut if you do that, you will find some funny things happen. You will find one error pop up in the terminal saying there is a failure when build, lets see what it said.\n\u0026gt; Task :spring-boot-project:spring-boot-tools:spring-boot-gradle-plugin:compileTestJava /Users/wjx/Documents/winter quarter/SWE261P/spring test/spring-boot/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java:179: error: method loadGradlePropertiesFrom in interface GradlePropertiesController cannot be applied to given types; .loadGradlePropertiesFrom(projectDir); ^ required: File,boolean found: File reason: actual and formal argument lists differ in length 1 error \u0026gt; Task :spring-boot-project:spring-boot-tools:spring-boot-gradle-plugin:compileTestJava FAILED I first double-check to make sure that\u0026rsquo;s not due to my mistake, I clone the repo again and run the test agian, and the error still exists.\nAccording to the error info, it seems like the method expected to receive 2 params but only get 1, but after I look into the compile test, I found that the design looks correct.\nThe abstract method loadGradlePropertiesFrom is design to input 1 param, and the IDE doesn\u0026rsquo;t pop up any error. I don\u0026rsquo;t know why Gradle said expected 2, but it may be some of the Gradle issue since it\u0026rsquo;d belong to their library.\nBut sometimes you may not want to test the huge system, in most cases, you just want to check the specific function you test. The whole system build obviously not suitable for that—it\u0026rsquo;s too slow and you need to spend a lot of time just waiting for the result. In this case, I prefer to use the test interface inside the IDE to call the specified test file individually. It will give you greater convenience and help with positioning problems.\nPartitioning and Functioning testing Systematic functional testing and partition testing are crucial for ensuring that a software application is reliable, functions as expected, and meets the users\u0026rsquo; needs. They are fundamental components of a thorough and effective software testing strategy.\nIn Functional testing, also known as black box testing, the tester evaluates the software by testing its functions according to the requirements, without any knowledge of the internal workings, structure, or implementation of the application. The focus is on what the system does, not how it does it.\nPartitioning testing, also known as equivalence partitioning, is a technique used in software testing to enhance efficiency and effectiveness by reducing the number of test cases needed to cover all possible input scenarios.\nI found my target test case at:\nspring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/CorsSampleActuatorApplicationTests.java Let\u0026rsquo;s check around the existing test case first:\npackage smoketest.actuator; import java.net.URI; import java.util.Map; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.LocalHostUriTemplateHandler; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpStatus; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ActiveProfiles; import static org.assertj.core.api.Assertions.assertThat; /** * Integration test for cors preflight requests to management endpoints. * * @author Madhura Bhave */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles(\u0026#34;cors\u0026#34;) class CorsSampleActuatorApplicationTests { private TestRestTemplate testRestTemplate; @Autowired private ApplicationContext applicationContext; @BeforeEach void setUp() { RestTemplateBuilder builder = new RestTemplateBuilder(); LocalHostUriTemplateHandler handler = new LocalHostUriTemplateHandler(this.applicationContext.getEnvironment(), \u0026#34;http\u0026#34;); builder = builder.uriTemplateHandler(handler); this.testRestTemplate = new TestRestTemplate(builder); } @Test void endpointShouldReturnUnauthorized() { ResponseEntity\u0026lt;?\u0026gt; entity = this.testRestTemplate.getForEntity(\u0026#34;/actuator/env\u0026#34;, Map.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); } @Test void preflightRequestToEndpointShouldReturnOk() throws Exception { RequestEntity\u0026lt;?\u0026gt; healthRequest = RequestEntity.options(new URI(\u0026#34;/actuator/env\u0026#34;)) .header(\u0026#34;Origin\u0026#34;, \u0026#34;http://localhost:8080\u0026#34;) .header(\u0026#34;Access-Control-Request-Method\u0026#34;, \u0026#34;GET\u0026#34;) .build(); ResponseEntity\u0026lt;?\u0026gt; exchange = this.testRestTemplate.exchange(healthRequest, Map.class); assertThat(exchange.getStatusCode()).isEqualTo(HttpStatus.OK); } @Test void preflightRequestWhenCorsConfigInvalidShouldReturnForbidden() throws Exception { RequestEntity\u0026lt;?\u0026gt; entity = RequestEntity.options(new URI(\u0026#34;/actuator/env\u0026#34;)) .header(\u0026#34;Origin\u0026#34;, \u0026#34;http://localhost:9095\u0026#34;) .header(\u0026#34;Access-Control-Request-Method\u0026#34;, \u0026#34;GET\u0026#34;) .build(); ResponseEntity\u0026lt;byte[]\u0026gt; exchange = this.testRestTemplate.exchange(entity, byte[].class); assertThat(exchange.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); } } The file name told us what this test case doing, the author want to make some test about the spring boot self-build tool, the actuator.\nSpring Boot Actuator provides developers with powerful capabilities to monitor and manage applications. It is one of the indispensable tools for Spring Boot applications in the production environment. And this testing is specifically for testing the actuator endpoint.\nOverall, this java test cross-origin resource sharing (CORS) preflight requests specifically for testing management endpoints (Actuator endpoints). In other words, the main goal is to verify the behavior of the CORS policy on the application\u0026rsquo;s management endpoint.\nBecause Actuator endpoints can expose sensitive information, it is important to manage the security of these endpoints. In a production environment, it is recommended to restrict access to these endpoints, such as only allowing access from specific IP addresses, or adding authentication through Spring Security.\nYou can see that author use @ActiveProfiles(\u0026quot;cors\u0026quot;) to make an Simple restrictions on the accessible scope.\nChecking the application-cors.properties file we found that there is two line of rule in the file. They are:\nmanagement.endpoints.web.cors.allowed-origins=http://localhost:8080 management.endpoints.web.cors.allowed-methods=GET Simple and easy to understand, server will only respond to the get request send through http://localhost:8080 others will be forbidden.\nAnd the author tests exactly based on what limitation they set.\nTo simplify, in 3 cases, the author did 3 things.\nTry to get the sensitive end point without any authorization, and expected to get 401 unauthorized response. Try to get the OK response with corret configuration Try to get the forbidden response with incorrect configuration The author leverages two key parameters for enabling the test function: the RESTful API and the port. Both serve as excellent parameters for partitioning. However, for a clearer delineation, the HTTP port is selected as the primary parameter for partition testing.\nIn the realm of computer networking, a port functions as a virtual point where network connections are initiated and terminated. Operating on a software level, ports enable multiple services or applications to listen for and transmit network requests using the same IP address.\nGiven that each port is uniquely identified by its number, within a range from 0 to 65535, this facilitates the creation of boundary-based test cases.\nThis specific range allows for the straightforward determination of the minimum and maximum port boundaries, which are 0 and 65535, respectively. Utilizing this information, one can devise a test case to ascertain whether the endpoint\u0026rsquo;s limit policy is adept at managing boundary events.\nAdditionally, a test case has been crafted to evaluate how the endpoint policy copes with non-existent ports, thereby assessing its effectiveness in handling cases that fall outside the defined bounds.\nThe specific code implementation is as follows：\n@Test @DisplayName(\u0026#34;port boundary test, maximum\u0026#34;) void preflightRequestPortBoundaryTestWhenCorsConfigInvalidShouldReturnForbidden() throws Exception { RequestEntity\u0026lt;?\u0026gt; entity = RequestEntity.options(new URI(\u0026#34;/actuator/env\u0026#34;)) .header(\u0026#34;Origin\u0026#34;, \u0026#34;http://localhost:65535\u0026#34;) .header(\u0026#34;Access-Control-Request-Method\u0026#34;, \u0026#34;GET\u0026#34;) .build(); ResponseEntity\u0026lt;byte[]\u0026gt; exchange = this.testRestTemplate.exchange(entity, byte[].class); assertThat(exchange.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); } @Test @DisplayName(\u0026#34;port boundary test2, minimum\u0026#34;) void preflightRequestPortBoundaryTest2WhenCorsConfigInvalidShouldReturnForbidden() throws Exception { RequestEntity\u0026lt;?\u0026gt; entity = RequestEntity.options(new URI(\u0026#34;/actuator/env\u0026#34;)) .header(\u0026#34;Origin\u0026#34;, \u0026#34;http://localhost:0\u0026#34;) .header(\u0026#34;Access-Control-Request-Method\u0026#34;, \u0026#34;GET\u0026#34;) .build(); ResponseEntity\u0026lt;byte[]\u0026gt; exchange = this.testRestTemplate.exchange(entity, byte[].class); assertThat(exchange.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); } @Test @DisplayName(\u0026#34;port boundary test3， out of bound\u0026#34;) void preflightRequestPortBoundaryTest3WhenCorsConfigInvalidShouldReturnForbidden() throws Exception { RequestEntity\u0026lt;?\u0026gt; entity = RequestEntity.options(new URI(\u0026#34;/actuator/env\u0026#34;)) .header(\u0026#34;Origin\u0026#34;, \u0026#34;http://localhost:99999\u0026#34;) .header(\u0026#34;Access-Control-Request-Method\u0026#34;, \u0026#34;GET\u0026#34;) .build(); ResponseEntity\u0026lt;byte[]\u0026gt; exchange = this.testRestTemplate.exchange(entity, byte[].class); assertThat(exchange.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); } Run the test case,all test cases pass as expected\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/springboottest1/","summary":"\u003cp\u003eSpring Boot is a project under the Spring Framework that simplifies developing, configuring, and deploying Spring-based applications. It promotes convention over configuration by offering pre-configured setups and auto-configuration based on project dependencies, eliminating much of the manual setup and configuration work. Spring Boot applications are stand-alone, containing an embedded web server for easy deployment as a single executable JAR. It offers opinionated defaults to reduce development effort, while still allowing for customization. Features like Actuator provide built-in endpoints for application monitoring and management. Primarily written in Java, Spring Boot supports other JVM languages like Kotlin and Groovy, making it versatile for various enterprise applications. Its goal is to enable quick application startup with less code and configuration hassle.\u003c/p\u003e","title":"Spring Boot Software Testing 1, Partitioning and Functioning testing"},{"content":" Prerequisite: You need to familiar with the box model\nUnderstanding the differences between clientHeight/clientLeft, offsetHeight/offsetLeft, and scrollTop/scrollLeft in the context of the Document Object Model (DOM) is crucial for effective web design and development. These properties are used to measure different aspects of elements\u0026rsquo; size and position in relation to their content, padding, border, and scroll position.\nClient clientHeight and clientLeft will give you the height and width of an element including padding. However, client will not calculate the size of the borders and margins. clientHeight/clientLeft are useful for understanding the visible part of an element, particularly for styling purposes or when dealing with scrolling. It\u0026rsquo;s a read-only property, which means you can not modify the params and generate action. Offset Similar with client, offsetHeight, offsetLeft will output the element height and width but including verical and horizontal border, in pixel. offsetHeight/offsetLeft are often used when you need to know the actual size of the element including borders and its position in the layout. Same as client, offsetHeight/offsetLeft is a read only param. Scroll scrollTop property gets or sets the number of pixels that an element\u0026rsquo;s content is scrolled vertically. scrollLeft is similar but for the horizontal axis. Unlike scrollTop, scrollLeft seldom use in current mainstream web pages since most of pages are developed vertically.\nscrollTop/scrollLeft are crucial for controlling and accessing the scroll position within an element, especially in scenarios involving dynamic content loading or scroll-based animations. Typically, scrollTop is a good property to calculate the whole window scroll distance. This distance can be used as a condition for partial attribute changes. For example, we can determine the entry and exit of the header by judging the distance the customer has scroll down. Here is the code:\n\u0026lt;script\u0026gt; const header = document.querySelector(\u0026#39;.header\u0026#39;) const module = document.querySelector(\u0026#39;.module\u0026#39;) window.addEventListener(\u0026#39;scroll\u0026#39;,function (){ const topLength = document.documentElement.scrollTop // if (topLength \u0026gt;= module.offsetTop){ // header.style.top = \u0026#39;0px\u0026#39; // } // else { // header.style.top = \u0026#39;-50px\u0026#39; // } header.style.top = topLength\u0026gt;=module.offsetTop?\u0026#39;0px\u0026#39;:\u0026#39;-50px\u0026#39; }) \u0026lt;/script\u0026gt; Besides, scrollTop is a writable param, which mean you can use it as a jump fumction that quickly scroll to specific position. This will be very helpful when you want to creat an sidebar navigator. Understanding these properties and their differences is key in web development, especially when dealing with dynamic layouts, responsive designs, and interactive content. Each property serves specific purposes and choosing the right one depends on the particular layout or behavior you want to achieve.\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/scroll-offset-client/","summary":"\u003cblockquote\u003e\n\u003cp\u003ePrerequisite: You need to familiar with the \u003ca href=\"https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model\"\u003ebox model\u003c/a\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eUnderstanding the differences between \u003ccode\u003eclientHeight\u003c/code\u003e/\u003ccode\u003eclientLeft\u003c/code\u003e, \u003ccode\u003eoffsetHeight\u003c/code\u003e/\u003ccode\u003eoffsetLeft\u003c/code\u003e, and \u003ccode\u003escrollTop\u003c/code\u003e/\u003ccode\u003escrollLeft\u003c/code\u003e in the context of the Document Object Model (DOM) is crucial for effective web design and development. These properties are used to measure different aspects of elements\u0026rsquo; size and position in relation to their content, padding, border, and scroll position.\u003c/p\u003e\n\u003ch3 id=\"client\"\u003eClient\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eclientHeight\u003c/code\u003e and \u003ccode\u003eclientLeft\u003c/code\u003e will give you the height and width of an element including padding. However, \u003ccode\u003eclient\u003c/code\u003e will not calculate the size of the borders and margins.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eclientHeight\u003c/code\u003e/\u003ccode\u003eclientLeft\u003c/code\u003e are useful for understanding the visible part of an element, particularly for styling purposes or when dealing with scrolling.\u003c/li\u003e\n\u003cli\u003eIt\u0026rsquo;s a read-only property, which means you can not modify the params and generate action.\n\u003cimg loading=\"lazy\" src=\"/posts/scroll-offset-client/client.webp\"\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch3 id=\"offset\"\u003eOffset\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eSimilar with \u003ccode\u003eclient\u003c/code\u003e, \u003ccode\u003eoffsetHeight\u003c/code\u003e, \u003ccode\u003eoffsetLeft\u003c/code\u003e will output the element height and width but  \u003cstrong\u003eincluding\u003c/strong\u003e verical and horizontal \u003cstrong\u003eborder\u003c/strong\u003e, in pixel.\u003c/li\u003e\n\u003cli\u003eoffsetHeight/offsetLeft are often used when you need to know the actual size of the element including borders and its position in the layout.\u003c/li\u003e\n\u003cli\u003eSame as client, \u003ccode\u003eoffsetHeight\u003c/code\u003e/\u003ccode\u003eoffsetLeft\u003c/code\u003e is a read only param.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/posts/scroll-offset-client/offset.webp\"\u003e\u003c/p\u003e","title":"Size measurement parameters -- client, offset and scroll"},{"content":"The scroll event in JavaScript is an important event that is triggered whenever an element or the window is scrolled. This event is particularly useful for creating dynamic effects based on the scroll position, such as parallax animations, infinite scrolling, or showing/hiding navigation bars. Here\u0026rsquo;s an overview of the scroll event:\n1. How it Works: The scroll event fires when the document view or an element has been scrolled. It applies to any scrollable element, including the window.\nIt\u0026rsquo;s a non-cancellable event, meaning you cannot use event.preventDefault() to block the scrolling action.\n2. Syntax: // For the entire window window.addEventListener(\u0026#39;scroll\u0026#39;, function() { // Code to execute on scrolling }); // For a specific element document.getElementById(\u0026#39;myElement\u0026#39;).addEventListener(\u0026#39;scroll\u0026#39;, function() { // Code to execute on scrolling within \u0026#39;myElement\u0026#39; }); 3. Use Case Lazy Loading: Triggering the loading of images or content as the user scrolls down. Animation: Implementing scroll-driven animations like revealing elements on scroll. Sticky Elements: Creating sticky headers or other elements that become fixed after a certain scroll point. Tracking Scroll Position: Monitoring the scroll position for analytics or user experience improvements. 4. Event Throttling The scroll event can fire at a high rate, which can lead to performance issues if the event handler does heavy computations or DOM manipulations.\nIt\u0026rsquo;s often advised to throttle the event, either by using a timer (like setTimeout or setInterval) or a library that provides throttling capabilities, to reduce the number of times the event handler is called.\nWhen using scroll event listener, always keep in mind to avoid extensive tasks inside the scroll event handler to prevent jank or sluggish scrolling. Besides, consider debouncing or throttling the event to improve performance and be mindful of accessibility implications, especially when changing layout or visibility of elements on scroll.\nIn summary, the scroll event is a versatile tool in JavaScript for creating interactive and dynamic effects based on the user\u0026rsquo;s scroll behavior. When used effectively and efficiently, it can greatly enhance the user experience on a web page.\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/scroll-event/","summary":"\u003cp\u003eThe \u003ccode\u003escroll\u003c/code\u003e event in JavaScript is an important event that is triggered whenever an element or the window is scrolled. This event is particularly useful for creating dynamic effects based on the scroll position, such as parallax animations, infinite scrolling, or showing/hiding navigation bars. Here\u0026rsquo;s an overview of the \u003ccode\u003escroll\u003c/code\u003e event:\u003c/p\u003e\n\u003ch3 id=\"1-how-it-works\"\u003e1. How it Works:\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eThe \u003ccode\u003escroll\u003c/code\u003e event fires when the document view or an element has been scrolled. It applies to any scrollable element, including the window.\u003c/p\u003e","title":"Scroll Event"},{"content":"Event Bubbling in JavaScript Event capturing is an event handling mechanism in JavaScript, contrasting with event bubbling. During the capturing phase, an event starts at the root node (usually the document object) and propagates down the DOM tree to the target element, where the event actually took place.\nThe process of event capturing is as follows:\nCapturing Phase: When an event occurs, it is first captured at the topmost node of the DOM tree, then propagates downwards, level by level, until it reaches the target element. During this phase, only those event listeners set to use capturing mode are triggered.\nTarget Phase: When the event reaches the target element, event listeners set for both capturing and bubbling modes are triggered.\nBubbling Phase: After the target phase, if the event is defined as a bubbling event (not all events bubble), it travels back up the DOM tree in the reverse direction, eventually reaching the root node.\nWhen adding event listeners, you can specify whether the listener is triggered during the capturing or bubbling phase. This is controlled by the third parameter of the addEventListener method. If this parameter is true, the listener is triggered during the capturing phase; if false (or omitted), it is triggered during the bubbling phase.\nfor example:\n\u0026lt;body\u0026gt; \u0026lt;div class=\u0026#34;father\u0026#34;\u0026gt; \u0026lt;div class=\u0026#34;son\u0026#34;\u0026gt;\u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;script\u0026gt; const father = document.querySelector(\u0026#39;.father\u0026#39;) const son = document.querySelector(\u0026#39;.son\u0026#39;) document.addEventListener(\u0026#39;click\u0026#39;,function(){ alert(\u0026#39;grandpa\u0026#39;) }, true) father.addEventListener(\u0026#39;click\u0026#39;,function(){ alert(\u0026#39;father\u0026#39;) }, true) son.addEventListener(\u0026#39;click\u0026#39;,function(){ alert(\u0026#39;son\u0026#39;) }, true) \u0026lt;/script\u0026gt; \u0026lt;/body\u0026gt; Event Bubbling in JavaScript In JavaScript, event bubbling is another event-handling mechanism where an event on a specific element propagates upwards through the DOM tree. This means the event doesn\u0026rsquo;t only trigger on the element it\u0026rsquo;s directly bound to, but also on its parent elements, grandparents, all the way up to the root element (usually the document object).\nThis mechanism allows us to set up an event listener on a parent element to catch and handle events occurring on multiple child elements, instead of setting up individual event listeners on each child element. This approach is known as event delegation.\nFor instance, if you have a list, you can set up a click event listener on the entire list rather than setting it up on each list item individually. When any item in the list is clicked, the event will first trigger on the clicked item and then bubble up the DOM tree, eventually triggering the listener set on the list.\nEvent bubbling can be stopped by calling the stopPropagation() method on the event object. This prevents the event from continuing to bubble up the DOM tree, restricting it to the element where it was initially triggered.\nfor example:\n\u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;UTF-8\u0026#34;\u0026gt; \u0026lt;meta name=\u0026#34;viewport\u0026#34; content=\u0026#34;width=device-width, initial-scale=1.0\u0026#34;\u0026gt; \u0026lt;title\u0026gt;Document\u0026lt;/title\u0026gt; \u0026lt;style\u0026gt; .father { width: 500px; height: 500px; background-color: yellow; } .son { width: 200px; height: 200px; background-color: red; } \u0026lt;/style\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;div class=\u0026#34;father\u0026#34;\u0026gt; \u0026lt;div class=\u0026#34;son\u0026#34;\u0026gt;\u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;script\u0026gt; const father = document.querySelector(\u0026#39;.father\u0026#39;) const son = document.querySelector(\u0026#39;.son\u0026#39;) document.addEventListener(\u0026#39;click\u0026#39;,function(){ alert(\u0026#39;grandpa\u0026#39;) }) father.addEventListener(\u0026#39;click\u0026#39;,function(){ alert(\u0026#39;father\u0026#39;) }) son.addEventListener(\u0026#39;click\u0026#39;,function(obj){ alert(\u0026#39;son\u0026#39;) obj.stopPropagation() }) \u0026lt;/script\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; ","permalink":"https://c57b4987.mrwblog.pages.dev/posts/event-flow-capture-bubble/","summary":"\u003ch2 id=\"event-bubbling-in-javascript\"\u003eEvent Bubbling in JavaScript\u003c/h2\u003e\n\u003cp\u003eEvent capturing is an event handling mechanism in JavaScript, contrasting with event bubbling. During the capturing phase, an event starts at the root node (usually the \u003ccode\u003edocument\u003c/code\u003e object) and propagates down the DOM tree to the target element, where the event actually took place.\u003c/p\u003e\n\u003cp\u003eThe process of event capturing is as follows:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eCapturing Phase\u003c/strong\u003e: When an event occurs, it is first captured at the topmost node of the DOM tree, then propagates downwards, level by level, until it reaches the target element. During this phase, only those event listeners set to use capturing mode are triggered.\u003c/p\u003e","title":"Event flow , capture, bubble and how to stop bubbling"},{"content":"Javascript timer function can make some code be excueted repeatedly over time.\nSyntax:\n// open setInterval(function,interaval-time) // close let t = setInterval(function,interaval-time) clearInterval(t) t: variable\ninteraval-time unit: ms\nExample:\n\u0026lt;body\u0026gt; \u0026lt;button class=\u0026#34;btn\u0026#34; disabled\u0026gt;aggree(5)\u0026lt;/button\u0026gt; \u0026lt;script\u0026gt; const btn = document.querySelector(\u0026#39;.btn\u0026#39;) let i = 5 let timer = setInterval(function(){ i-- btn.innerHTML = `aggree(${i})` if (i === 0){ clearInterval(timer) btn.disabled = false btn.innerHTML = \u0026#39;aggree\u0026#39; } },1000) \u0026lt;/script\u0026gt; \u0026lt;/body\u0026gt; ","permalink":"https://c57b4987.mrwblog.pages.dev/posts/timer/","summary":"\u003cp\u003eJavascript timer function can make some code be excueted repeatedly over time.\u003c/p\u003e\n\u003cp\u003eSyntax:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// open\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003esetInterval\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kd\"\u003efunction\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nx\"\u003einteraval\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"nx\"\u003etime\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// close\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003et\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003esetInterval\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kd\"\u003efunction\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nx\"\u003einteraval\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"nx\"\u003etime\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003eclearInterval\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003et\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003ccode\u003et\u003c/code\u003e: variable\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003einteraval-time\u003c/code\u003e unit: ms\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eExample:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebody\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebutton\u003c/span\u003e \u003cspan class=\"na\"\u003eclass\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;btn\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003edisabled\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003eaggree(5)\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ebutton\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003escript\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ebtn\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003equerySelector\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;.btn\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003etimer\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003esetInterval\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kd\"\u003efunction\u003c/span\u003e\u003cspan class=\"p\"\u003e(){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nx\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e--\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nx\"\u003ebtn\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003einnerHTML\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"sb\"\u003e`aggree(\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003ei\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e)`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003eclearInterval\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etimer\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003ebtn\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edisabled\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003ebtn\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003einnerHTML\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;aggree\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e},\u003c/span\u003e\u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003escript\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ebody\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"Timer"},{"content":"ClassList can help reduce the redundancy of .style method and resolve the ClassName overwrite risk.\nSytax:\n// add a class element.classList.add(\u0026#39;className\u0026#39;) // delete a class element.classList.remove(\u0026#39;className\u0026#39;) // switch a class element.classList.toggle(\u0026#39;className\u0026#39;) Example:\n\u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;UTF-8\u0026#34;\u0026gt; \u0026lt;meta name=\u0026#34;viewport\u0026#34; content=\u0026#34;width=device-width, initial-scale=1.0\u0026#34;\u0026gt; \u0026lt;title\u0026gt;Document\u0026lt;/title\u0026gt; \u0026lt;style\u0026gt; .box { width: 200px; height: 200px; color: #333; } .active { color: red; background-color: pink; } \u0026lt;/style\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;div class=\u0026#34;box\u0026#34;\u0026gt;text\u0026lt;/div\u0026gt; \u0026lt;script\u0026gt; //get element const box = document.querySelector(\u0026#39;.box\u0026#39;) //change stylew by adding class box.classList.add(\u0026#39;active\u0026#39;) // delete class box.classList.remove(\u0026#39;active\u0026#39;) //switch class box.classList.toggle(\u0026#39;active\u0026#39;) \u0026lt;/script\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; keep in mind that the running logic of toggle is run the detect if the class existed in the element, if yes, delete, if no, add up\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/operate-style/","summary":"\u003cp\u003eClassList can help reduce the redundancy of .style method and resolve the ClassName overwrite risk.\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eSytax:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e// add a class\nelement.classList.add(\u0026#39;className\u0026#39;)\n// delete a class \nelement.classList.remove(\u0026#39;className\u0026#39;)\n// switch a class\nelement.classList.toggle(\u0026#39;className\u0026#39;)\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eExample:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e\u0026lt;!DOCTYPE html\u0026gt;\n\u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt;\n\u0026lt;head\u0026gt;\n    \u0026lt;meta charset=\u0026#34;UTF-8\u0026#34;\u0026gt;\n    \u0026lt;meta name=\u0026#34;viewport\u0026#34; content=\u0026#34;width=device-width, initial-scale=1.0\u0026#34;\u0026gt;\n    \u0026lt;title\u0026gt;Document\u0026lt;/title\u0026gt;\n    \u0026lt;style\u0026gt;\n        .box {\n            width: 200px;\n            height: 200px;\n            color: #333;\n        }\n        .active {\n            color: red;\n            background-color: pink;\n        }\n    \u0026lt;/style\u0026gt;\n\u0026lt;/head\u0026gt;\n\u0026lt;body\u0026gt;\n    \u0026lt;div class=\u0026#34;box\u0026#34;\u0026gt;text\u0026lt;/div\u0026gt;\n    \u0026lt;script\u0026gt;\n        //get element\n        const box = document.querySelector(\u0026#39;.box\u0026#39;)\n        //change stylew by adding class\n        box.classList.add(\u0026#39;active\u0026#39;)\n        // delete class\n        box.classList.remove(\u0026#39;active\u0026#39;)\n        //switch class\n        box.classList.toggle(\u0026#39;active\u0026#39;)\n    \u0026lt;/script\u0026gt;\n\u0026lt;/body\u0026gt;\n\u0026lt;/html\u0026gt;\n\u003c/code\u003e\u003c/pre\u003e\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003ekeep in mind that the running logic of \u003ccode\u003etoggle\u003c/code\u003e is run the detect if the class existed in the element, if yes, delete, if no, add up\u003c/strong\u003e\u003c/p\u003e","title":"Control CSS using classList"},{"content":"DOM query Slect first match element document.querySelector(\u0026#39;css selector\u0026#39;) Slect all match element document.querySelectorAll(\u0026#39;css selector\u0026#39;) return is fake array which no work with push and pop method\nModification using DOM modify text content \u0026lt;body\u0026gt; \u0026lt;div class=\u0026#34;box\u0026#34;\u0026gt;content\u0026lt;/div\u0026gt; \u0026lt;script\u0026gt; const box = document.querySelector(\u0026#39;.box\u0026#39;) box.innerText = \u0026#39;content changed\u0026#39; box.innerHTML = \u0026#39;\u0026lt;strong\u0026gt;content changed\u0026lt;/strong\u0026gt;\u0026#39; \u0026lt;/script\u0026gt; \u0026lt;/body\u0026gt; innerText method will not parse tags, exp: \u0026lt;strong\u0026gt;hello\u0026lt;/strong\u0026gt; will return \u0026lt;strong\u0026gt;hello\u0026lt;/strong\u0026gt; rather hello\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/dom/","summary":"\u003ch2 id=\"dom-query\"\u003eDOM query\u003c/h2\u003e\n\u003ch3 id=\"slect-first-match-element\"\u003eSlect first match element\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003equerySelector\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;css selector\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"slect-all-match-element\"\u003eSlect all match element\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003equerySelectorAll\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;css selector\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cblockquote\u003e\n\u003cp\u003ereturn is fake array which no work with \u003ccode\u003epush\u003c/code\u003e and \u003ccode\u003epop\u003c/code\u003e method\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"modification-using-dom\"\u003eModification using DOM\u003c/h2\u003e\n\u003ch3 id=\"modify-text-content\"\u003emodify text content\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ebody\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ediv\u003c/span\u003e \u003cspan class=\"na\"\u003eclass\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;box\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003econtent\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ediv\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003escript\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ebox\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003equerySelector\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;.box\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003ebox\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003einnerText\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;content changed\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003ebox\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003einnerHTML\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e  \u003cspan class=\"s1\"\u003e\u0026#39;\u0026lt;strong\u0026gt;content changed\u0026lt;/strong\u0026gt;\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003escript\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ebody\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cblockquote\u003e\n\u003cp\u003einnerText method will not parse tags, exp: \u003ccode\u003e\u0026lt;strong\u0026gt;hello\u0026lt;/strong\u0026gt;\u003c/code\u003e will return \u003ccode\u003e\u0026lt;strong\u0026gt;hello\u0026lt;/strong\u0026gt;\u003c/code\u003e rather \u003cstrong\u003ehello\u003c/strong\u003e\u003c/p\u003e\n\u003c/blockquote\u003e","title":"DOM -- Document Object Model"},{"content":"\nMearge conflict resolution: Edit the confilct file manually and then commit to branch\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/git-workflow-conflict/","summary":"\u003cp\u003e\u003cimg alt=\"git workflow\" loading=\"lazy\" src=\"/posts/git-workflow-conflict/git-workflow.png\" title=\"git workflow\"\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eMearge conflict resolution: Edit the confilct file manually and then commit to branch\u003c/p\u003e\n\u003c/blockquote\u003e","title":"Git classic workflow and merge conflict solution"},{"content":"Mega CMD is an software that provide similar function of QNAP HBS, but I don\u0026rsquo;t know why they can\u0026rsquo;t just integrated their function into HBS. And it is a command line system, though I\u0026rsquo;m not afraid of command but it truly increase the inconvenience for those who just want to make a backup. Most seriously, the way to enter the cmd window won\u0026rsquo;t show up on their readme.md but only in the introduction of the app store, with an very blurry picture. That\u0026rsquo;s ridiculous. I hope they can make the doc clearer in the future.\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/megacmd/","summary":"\u003cp\u003e\u003ca href=\"https://github.com/meganz/MEGAcmd\"\u003eMega CMD\u003c/a\u003e is an software that provide similar function of QNAP \u003ca href=\"https://www.qnap.com/en-us/software/hybrid-backup-sync\"\u003eHBS\u003c/a\u003e, but I don\u0026rsquo;t know why they can\u0026rsquo;t just integrated their function into HBS. And it is a command line system, though I\u0026rsquo;m not afraid of command but it truly increase the inconvenience for those who just want to make a backup. Most seriously, the way to enter the cmd window won\u0026rsquo;t show up on their readme.md but only in the introduction of the app store, with an very blurry picture.  That\u0026rsquo;s ridiculous. I hope they can make the doc clearer in the future.\u003c/p\u003e","title":"How to enter QNAP NAS Mega CMD"},{"content":" Prerequisite: Before proceeding, it is essential to have a static public IP. If you do not already have one, kindly reach out to your ISP for assistance. Please note that if you are unfamiliar with QNAP NAS, this article may not cater to your requirements.\nFor several reasons, you cannot connect to many cloud storage server like google drive in China, which make it difficult to fully function the HBS3(Hybrid Backup Sync). To solve those problem, I add a proxy gateway to my family network and make some configuration to make sQure the Transparent proxy working properly. However, this led to troubles with the Dynamic Domain Name System (DDNS) due to the changes in configuration. This issue had persisted for quite some time until I finally discovered the solution to the mystery.\nInitially, I encountered issues with Myqnapcloud DDNS not functioning despite correctly configuring port forwarding or DMZ on my router. However, upon inspecting the DDNS IP address and comparing it with my public IP, I discovered that they did not match. I was surprised to find that the DDNS was erroneously pointing to my proxy IP. After couples of searches, finally I realized that I was not fully familiar with the working principle of DDNS, and the proxy routing function treated the DDNS server data as a flow requiring proxy, causing the issue.\nIn order to solve the above problems,you need to take the following steps:\n1.Filed a ticket with QNAP to obtain a list of their ddns name servers.\n2.Added these servers to your routing rules to ensure a direct connection when the ddns name server tries to trace the correct IP.\n3.Ensured that the port mapping/port forwarding function is enabled and properly configured in both the router and proxy gateway. This needs to be done twice to ensure that the correct ports are open on both sides.\nhttps://auth.api.myqnapcloud.com https://auth.myqnapcloud.io https://edge.api.myqnapcloud.com https://edge.myqnapcloud.io https://core2.api.myqnapcloud.com https://core2.myqnapcloud.io\nThe above list is what I know QNAP use for DDNS, if no, raise a ticket to ask them again.\nYour myqnapcloud may functioning now. Overall, it is not a formidable cases when you know the running theory of DDNS and Tproxy. Myqnapcloud is a good app, it help me save a lot of configuration step, but at the same time, it also makes me omit some underlying logic of DDNS and hinder me to solve the wrong pointing issue.\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/qnap_ddns/","summary":"\u003cblockquote\u003e\n\u003cp\u003ePrerequisite: Before proceeding, it is essential to have a static public IP. If you do not already have one, kindly reach out to your ISP for assistance. Please note that if you are unfamiliar with QNAP NAS, this article may not cater to your requirements.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003cp\u003eFor several reasons, you cannot connect to many cloud storage server like google drive in China, which make it difficult to fully function the HBS3(Hybrid Backup Sync). To solve those problem, I add a proxy gateway to my family network and make some configuration to make sQure the Transparent proxy working properly. However, this led to troubles with the Dynamic Domain Name System (DDNS) due to the changes in configuration. This issue had persisted for quite some time until I finally discovered the solution to the mystery.\u003c/p\u003e","title":"How to make QNAP NAS DDNS functional while using Tproxy"},{"content":"Abstract There is no absolute safe disguise, all protocols have risks of detected.\nCommon attack made by middle box Passive analysis (Traffic characteristic, PoC vulnerability) Usually use for plain text protocol or TLS handshake.\nActive analysis Usually use for Shadowsocks, V2Ray, TLS v1.3 (obtian svers\u0026rsquo;s SSL certificate)\nreplay package\nSome obvious charecteristics of proxy traffic. Long connection Most HTTP traffic is short connection.\nbidireaction flow 99% of Web traffic(HTTP) is one-way flow, which is a group of request match a group of response, few website use websocket.\nHigh traffic Lack of reasons to justify large traffic.\nHigh connection numbers Normally a website will only create one websocket connection, hard to explain why there are 20-30 connections existed.\nPoint to point IP to IP, high encryption, high traffic, thus \u0026mdash;- high suspiciousness\nThose charecteristics are always exist in proxy protocols, it will be hard to erase.\nTLS traffic risk analysis ClientHello TLS ClientHello have fingerprint\nIf access website using programs default fingerprint(for example: Go TLS) and match the features above. The risk that will be recongized by proxy will be high.\nIran firewall will reject curl and wget fingerprint request for non-whitelist, Go TLS and browsers fingerprint will be allowed. Recommende to connect by using browser\u0026rsquo;s fingerprint. (Go project uTLS) Note: this repository is disrepair and the chrome fingerprint remain at Chrome 83, it may be a risk. A changable option of the above is here , Chrome 104 fingerprint is currently added.\nServer Name Idication (SNI) Highest risk for free domains, cheap domains will also contain risk.\nTLS connection version TlS v1.3 has the highest risk, all contents after the Server Hello will be all encrypted, middlebox need active detection to obtain server certificate.\nTLS v1.2 will be considered as median risk. All certificates exchange will be in plain text, middle box can verify it through intercept traffic.\nSSL v3/TLS v1.0/TLS v1.1 have the lowest risk , there is few traffic here, in other words, fewer sample. However, using out-dated encryption have risk of being attacked, not recommended.\nTLS server certificate Self-signed certificate have the highest risk. Second are cloudflare certificate and Let\u0026rsquo;s Encrypt because they are free.\nAlmost no people will spent hunders of dollars on certificate.\nReport: New detection method that capable to detect Fake TLS traffic Analysis Both MTPRoto FakeTLS and Shadow TLS(v1/v2) are simulate a TLS handshake with trusted certificate to circumvent whitelist. Both two protocols are nearly perfect, they can be verified as valid client while handshake.\nHow to verify client of MTProto FakeTLS ClientHello package remove ramdom field and make a whole package for hmac, key will be secret, also use the hmac on sevrer to verify client, random have one-time processing, it will fallback to real web server if failed. Indentification method: TLS handshake of MTProto not standardize, firewall can intercept the hostCert package and judge the length. The lenght of hostCert will be ramdon, between 1024-4096 bit. (mtg-faketls)\nShadow TLS v1 won\u0026rsquo;t verify client Identification method: send a request to the sever through curl, curl will failed.\nHow Shadow TLS v2 verify client After client request, sever will return the orgin data as challenge response and use password to hmac. The server can verif the client using same hmac. Due to the return data have randomness and can also achieve one-time verification, middlebox can not react the challenge response if they don\u0026rsquo;t have password, hence, it will be more safer compare with MTproto handshake. New measure to detect client Most protocols security are based on server verify the client, but the client will not verify sever\u0026rsquo;s validity. In other words, one-way authentication Firewall can detect the server reaction by using fake server package. Using reverse dectection to check if the clients are real browser\nMTProto use hmac algorithm in ServerHello and will not affected by this measure.\nHow PoC identify the Shadow TLS v2 protocol desigin Github docs Firewall will intercept a normal TCP connection randomly. After they get TLS ClientHello, they will hijack the request content\u0026rsquo;s SNI field to real SNI server. After the TLS handshake finished, client of Shadow TLS will incert server\u0026rsquo;s challenge response 8 bit before the Application Data.\nAt this moment, because the opposite side is a real real TLS server, handshake with Shadow TLS client will be successful. But afer the hmac sent, server will drop an Alert(Encrypted Application Data) bacause it is not a negotiated TLS encryption. After that, the server will FIN or RST the TCP connection, at this time the ShadowTLS will be identified and can be block by ip precisely.\nProxy procotols will normally use multi connection. Middlebox can precisely identify the client by merely pick one of those connection.\nCurrently recommend proxy protocol Hystertia, TUIC(QUIC) The firewall does not block or interfere with QUIC, so you can use it with confidence. \u0026ldquo;This article is translate from Coia channel ,some emotional expressions have been deleted. This article not represent personal opinion \u0026quot;\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/middle_box/","summary":"\u003ch1 id=\"abstract\"\u003eAbstract\u003c/h1\u003e\n\u003cp\u003eThere is no absolute safe disguise, all protocols have risks of detected.\u003c/p\u003e\n\u003ch2 id=\"common-attack-made-by-middle-box\"\u003eCommon attack made by middle box\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003ePassive analysis (Traffic characteristic, PoC vulnerability)\nUsually use for plain text protocol or TLS handshake.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eActive analysis\nUsually use for Shadowsocks, V2Ray, TLS v1.3 (obtian svers\u0026rsquo;s SSL certificate)\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ereplay package\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"some-obvious-charecteristics-of-proxy-traffic\"\u003eSome obvious charecteristics of proxy traffic.\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eLong connection\nMost HTTP traffic is short connection.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ebidireaction flow\n99% of Web traffic(HTTP) is one-way flow, which is a group of request match a group of response, few website use websocket.\u003c/p\u003e","title":"How Middleboxs Identify Proxy Traffics"},{"content":"If you use systemctl status nginx to check nginx status you may find a pid error appear on status panel. The words that appear may be :\nCan\u0026#39;t open PID file /run/nginx.pid (yet?) after start: Operation not permitted Or Can\u0026#39;t open PID file /var/run/nginx.pid (yet?) after start: No such file or directory This is becasue the pid file not generate before the nginx booted. The solution is to add following sentence into /usr/lib/systemd/system/nginx.service, it will let nginx wait 0.1s before executing the executable.\nExecStartPost=/bin/sleep 0.1\nAdd this sentence to the [service] part.\nRload and restart the nginx\nsystemctl daemon-reload systemctl restart nginx Problem fixed.\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/nginx_error/","summary":"\u003cp\u003eIf you use \u003ccode\u003esystemctl status nginx\u003c/code\u003e to check nginx status you may find a pid error appear on status panel.  The words that appear may be :\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eCan\u0026#39;t open PID file /run/nginx.pid (yet?) after start: Operation not permitted\nOr\nCan\u0026#39;t open PID file /var/run/nginx.pid (yet?) after start: No such file or directory\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThis is becasue the pid file not generate before the nginx booted.\nThe solution is to add following sentence into \u003ccode\u003e/usr/lib/systemd/system/nginx.service\u003c/code\u003e, it will let nginx wait 0.1s before executing the executable.\u003c/p\u003e","title":"Nginx pid error fix"},{"content":"Project Objectives: The project goal is is to benchmark Redis database in different architecture environments, analyze the performance differences and find the root cause of the components and class that cause the performance issue of riscV. Provides reference for optimization options for future servers based on the Risc V architecture.\nOutcome: The outcome will be a comprehensive report including list of the potencial performance bottleneck points and optimization advisements. This document will help future developers to optimize the performance of RiscV architecture servers and improve overall operating efficiency.\nMy Role: My role is Reasearch Assistance leader\nMy Responsibilities: As a Research Assistant, I spearheaded a collaborative project to optimize Redis performance on RISC-V architecture. Working alongside a team of three, I initiated the project by defining its scope and objectives, ensuring alignment with the professor\u0026rsquo;s vision. Through rigorous testing and analysis, I identified and resolved technical challenges, ultimately developing an automated system that significantly enhanced efficiency and accelerated our research process. My contributions to this project played a pivotal role in advancing our understanding of Redis performance on RISC-V and contributing to the broader field of computer science.\nDeliverables: As the Result, the provided document will be ultimatily intergrated into research article and will be published well-known academic journals.\n","permalink":"https://c57b4987.mrwblog.pages.dev/posts/new/","summary":"\u003cp\u003e\u003cstrong\u003eProject Objectives\u003c/strong\u003e: The project goal is is to benchmark Redis database in different architecture environments, analyze the performance differences and find the root cause of the components and class that cause the performance issue of riscV. Provides reference for optimization options for future servers based on the Risc V architecture.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eOutcome\u003c/strong\u003e: The outcome will be a comprehensive report including list of the potencial performance bottleneck points and optimization advisements. This document will help future developers to optimize the performance of RiscV architecture servers and improve overall operating efficiency.\u003c/p\u003e","title":""}]