Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tests for Storage Extension and File Rotation #1427

Merged
merged 11 commits into from
Oct 13, 2023

Conversation

vasireddy99
Copy link
Contributor

@vasireddy99 vasireddy99 commented Oct 6, 2023

Description:
PR to add Tests for Storage Extension Restart scenarios and File Rotation

Thread.sleep is used to give enough time for file operations, collector(stop/start).

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@vasireddy99 vasireddy99 requested a review from a team as a code owner October 6, 2023 23:22
@vasireddy99 vasireddy99 marked this pull request as draft October 6, 2023 23:22
@vasireddy99 vasireddy99 marked this pull request as ready for review October 11, 2023 18:45
} catch (IOException e) {
throw new RuntimeException("Error writing to File A.", e);
}
Thread.sleep(5000);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you van validate the log entries so far here so that you don't need to add a sleep. that will block in a safe way before you move with the rest of the tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that validation can be done, but the thread here is making sure to give enough time for the file operations to be done. So even if we do the validation without the thread, since the log file is not generated it would lead FileNotFoundException.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is writing to the file a blocking operation? Why do you need to wait? What file operations are you referring to?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what operations needs to be done?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File operations i meant here are to create and write data to File A etc. it takes considerable time for creating and writing to file.
So without the thread.sleep the collector is not able to parse log line, since it seems the file testlogA.log didn't have the line written to it yet.

        java.lang.AssertionError: 
        Expecting actual:
          ["Message in renamed file - line 1",
            "Message in renamed file - line 2",
            "Message in renamed file - line 3"]
        to contain exactly in any order:
          ["Message in File A",
            "Message in renamed file - line 1",
            "Message in renamed file - line 2",
            "Message in renamed file - line 3"]
        but could not find the following elements:
          ["Message in File A"]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is why I suggested that you add a validateLogs instead of a Thread.sleep to validate only "Message in File A". It will block until the lines are sent to cwlogs. This will guarantee that it is safe to continue with the tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Committed the changes.

Comment on lines +60 to 61
private Path logDirectory;
private GenericContainer<?> collector;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does test parallelism work with the framework we are using? Does having these in the Class scope have a potential to cause conflicts if test cases are ran in parallel?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried running with ./gradlew test --rerun-tasks --info --parallel to have optimal number of threads to use no conlicts were seen. We are also using specific path/file within the directory so parallel wouldn't be a problem IMO

String logStreamName = "storageExtension-logstream-" + uniqueID;
collector = createAndStartCollector("/configurations/config-storageExtension.yaml", logStreamName);
File tempFile = new File(logDirectory.toString(), "storageExtension.log");
Thread.sleep(5000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why sleep here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sleep is similar as here, its just to wait for the collector to start watching the file.

fileWriter.write("First Message after collector is stopped" + "\n");
fileWriter.write("Second Message after the collector is stopped" + "\n");
fileWriter.write("Third Message after the collector is stopped" + "\n");
fileWriter.flush();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is flush called inside the try block here but outside of it on line 144?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually no specific reason, modified .

String expectedLogPath = logDirectory.toString();
logFilePaths.add(expectedLogPath + "/storageExtension.log");

validateLogs(logStreamName , logFilePaths);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to validate logs twice? Could we run through the start -> write -> stop -> write -> start -> stop cycle then validate once?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validate is behaving like a sleep here. we need to make sure that logs were read before stopping the collector.

Copy link
Contributor Author

@vasireddy99 vasireddy99 Oct 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to make sure that logs were read before stopping the collector.
I tend to agree with that. After changes now it is doing - start -> write -> validate->stop -> write -> start -> stop and then it validates again.

} catch (IOException e) {
throw new RuntimeException("Error writing to File A.", e);
}
Thread.sleep(5000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is writing to the file a blocking operation? Why do you need to wait? What file operations are you referring to?

Comment on lines 275 to 279
System.out.println("Actual Logs - Log lines From Cloudwatch");
messageToValidate.forEach(System.out::println);

System.out.println("Expected logs- Log lines from log file");
lines.forEach(System.out::println);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's be more thoughtful about what we are printing to std out. We should only need to print if there is a failure. And in the case of the failure it should be descriptive to tell us what was expected and what was actually given.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I have added it for easy lookout on whats' validated. if we should only need to print during failure then the assertions will log the actual/expected when in failure, removed the print statements

for (String logFilePath : logFilePaths) {
InputStream inputStream;
//Check whether the filePath is from resource folder.
if (getClass().getResource(logFilePath) != null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is still the boolean flag behaviour disguised.....

my suggestion was to change the function signature to use

void validateLogs(String testLogStreamName, List<InputStream> inputStreams) throws Exception {

Another option is to create two functions, one that should only be used for resources paths and another that is used only for local paths.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, now I see the suggestion. Modified.

printWriter.println("Third Message, collector is running");
printWriter.flush();

Thread.sleep(5000);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I bet this could be removed and the tests would still succeed.

@vasireddy99 vasireddy99 merged commit c688310 into aws-observability:terraform Oct 13, 2023
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants