How to track packages downloads on Nuget.Server? - c#

We're using private Nuget repository for serving packages in intranet environment. Is it possible to track what packages are downloaded to create basic statistics? For example which packages were downloaded the most, etc.

Presumably you have an ASP.NET application which uses the NuGet.Server package.
Then it would be quite easy to add some logging. You can decorate the PackageService:
public class MyPackageService : IPackageService
{
public MyPackageService(PackageService packageService)
{
_PackageService = packageService;
}
private readonly PackageService _PackageService;
public void CreatePackage(HttpContextBase context)
{
_PackageService.CreatePackage(context);
}
public void DeletePackage(HttpContextBase context)
{
_PackageService.DeletePackage(context);
}
public void DownloadPackage(HttpContextBase context)
{
// LOG HERE
Log(context);
_PackageService.DownloadPackage(context);
}
public void PublishPackage(HttpContextBase context)
{
_PackageService.PublishPackage(context);
}
}
and then change Routes.cs to rebind to MyPackageService.
public static class NuGetRoutes {
public static void Start() {
NinjectBootstrapper.Kernel.Rebind<IPackageService>().To<MyPackageService>();
MapRoutes(RouteTable.Routes);
}
//...
}

Related

Sharing Driver between Step files in C#

I'm having an issue with sharing my driver between step files in my projects. I've done a lot of googling online and come up with a solution using the IObjectContainer. Which I believe is correct? However, it doesn't seem to work. It gets stuck. I don't quite understand where IObjectContainer gets instantiated. Below is the code of my Hooks file and one of my Step Files:
Hooks File:
public class RDM_Hooks
{
private IObjectContainer _objectContainer;
public RDM_Website<ChromeDriver> RDM_Website;
public void WebDriverSupport(IObjectContainer objectContainer)
{
_objectContainer = objectContainer;
}
[BeforeScenario]
public void InitWebDriver()
{
RDM_Website = new RDM_Website<ChromeDriver>();
_objectContainer.RegisterInstanceAs<RDM_Website<ChromeDriver>>(RDM_Website);
}
[AfterScenario]
public void DisposeWebDriver()
{
RDM_Website.SeleniumDriver.Quit();
RDM_Website.SeleniumDriver.Dispose();
}
}
Steps File:
public class RDM_LoginSteps
{
private RDM_Website<ChromeDriver> RDM_Website;
public RDM_LoginSteps(RDM_Website<ChromeDriver> rdm_website)
{
RDM_Website = rdm_website;
}
[Given(#"I am on the homepage")]
public void GivenIAmOnTheHomepage()
{
RDM_Website.RDM_Homepage.VisitHomePage();
}
}
I think im missing something somewhere but any info i've found online doesn't go further than the above and I'm a bit lost.
I simply want all my step files to share the same browser so I'm able to have all my login steps using one file and do something else on another for example.
Here's the Hook file I use my UI tests
[Binding]
internal sealed class WebHooks
{
private readonly IObjectContainer _objectContainer;
public WebHooks(IObjectContainer objectContainer)
{
_objectContainer = objectContainer;
}
[BeforeScenario("web")]
public void BeforeWebScenario()
{
//HACK:
//https://stackoverflow.com/questions/43571119/loading-of-unpacked-extensions-is-disabled-by-the-administrator
var options = new ChromeOptions();
options.AddArgument("--start-maximized");
options.AddAdditionalCapability("useAutomationExtension", false);
options.AddArgument("--no-sandbox");
options.AddArgument("--whitelisted-ips=''");
//HACK: this fixes issue with not being able to find chromedriver.exe
//https://stackoverflow.com/questions/47910244/selenium-cant-find-chromedriver-exe
var webDriver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), options, TimeSpan.FromMinutes(15));
webDriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(40);
_objectContainer.RegisterInstanceAs<IWebDriver>(webDriver);
}
[AfterScenario("web")]
public void AfterWebScenario()
{
var webDriver = _objectContainer.Resolve<IWebDriver>();
if (webDriver == null) return;
webDriver.Close();
webDriver.Dispose();
}
}
It looks like you're missing the [Binding] attribute on the hook class.
I also don't see you getting the reference out of the container to Dispose of it when you are done.
I don't know what RDM_Website is doing, but I'd keep you hooks clean with just reference to the driver and nothing else.
Then reference it in your step class like
[Binding]
public class Steps
{
private readonly IWebDriver _webDriver;
public Steps(IWebDriver webDriver)
{
_webDriver = webDriver;
}
}
the BoDi container is already hooked up for you

Use Zenject FromSubContainerResolve on ProjectContext to SceneContext

I have a Unity + Zenject setup with a ProjectInstaller with some global dependencies that adhere to a "modal" interface, e.g.,
public class ProjectInstaller : MonoInstaller {
public override void InstallBindings() {
Container.Bind<ModalManager>().AsSingle();
Container.Bind<Modal>().To<DialogManager>().AsSingle();
}
}
Some modals are only relevant to certain scenes, so I bind those in the SceneInstaller:
public class SceneInstaller : MonoInstaller {
public override void InstallBindings() {
Container.BindInterfacesAndSelfTo<InventoryManager>()
.FromComponentInNewPrefab(InventoryPrefab)
.AsSingle()
}
}
I want to manage all modals from the single ModalManager, defined at the project scope. So it has a List<Modal> binding:
public class ModalManager : MonoBehaviour {
[Inject]
protected List<Modal> _modals;
}
When I run this, the ModalManager only gets a single modal: the one defined in the project scope. In my understanding the SceneContext is a subcontainer of the ProjectContext. So I should be able to use FromSubContainerResolve in the ProjectInstaller to bind items in the child scene, perhaps by adding a line like:
// ProjectInstaller.cs
public override void InstallBindings() {
// ...
Container.Bind<Modal>().To<InventoryManager>().FromSubContainerResolve();
}
But I'm not sure which of the eleventy FromSubContainerResolve methods make sense for this case. They all seem pertinent to prefabs with a game object context, not for use from within the ProjectContext.
Does this use case make sense? Is there an easier or better way?
The problem is that that ModalManager can only be injected with dependencies that are added directly to ProjectContext. For these kinds of problems I recommend using the following pattern:
public interface IModal
{
}
public class ModalManager
{
private readonly List<IModal> _modals = new List<IModal>();
public IReadOnlyList<IModal> Modals
{
get { return _modals; }
}
public void AddModal(IModal modal)
{
_modals.Add(modal);
}
public bool RemoveModal(IModal modal)
{
return _modals.Remove(modal);
}
}
public class ModalRegisterHandler : IInitializable, IDisposable
{
private readonly List<IModal> _modals;
private readonly ModalManager _modalManager;
public ModalRegisterHandler(
// We need to use InjectSources.Local here, otherwise we will
// add any project context modals again in each scene
[Inject(Source = InjectSources.Local)]
List<IModal> modals, ModalManager modalManager)
{
_modals = modals;
_modalManager = modalManager;
}
public void Initialize()
{
foreach (var modal in _modals)
{
_modalManager.AddModal(modal);
}
}
public void Dispose()
{
// We don't want ModalManager to retain references to Modals defined in unloaded scenes
// (dispose is executed on scene unload)
foreach (var modal in _modals)
{
_modalManager.RemoveModal(modal);
}
}
}
public class SceneInstaller : MonoInstaller
{
public override void InstallBindings()
{
Container.Bind<IModal>().To<FooModal>();
Container.Bind<IModal>().To<BarModal>();
}
}
public class ProjectInstaller : MonoInstaller
{
public override void InstallBindings()
{
// We use CopyIntoDirectSubContainers so that ModalRegisterHandler gets automatically added to every
// scene context
Container.BindInterfacesTo<ModalRegisterHandler>().AsSingle().CopyIntoDirectSubContainers();
Container.Bind<ModalManager>().AsSingle();
Container.Bind<IModal>().To<QuxModal>();
Container.Bind<IModal>().To<FizzModal>();
}
}

How to create an automation test for a workflow

I am working on a workflow project that has 19 scenarios for testing the whole system and 34 steps.
So, my question is, how can I create an automation test for it?
My current approach is:
Create an integrated test per each scenario, and then create the main system test to run all integrated tests.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
namespace Project1
{
// Unit tests
public class UnitTest_step1
{
public void RunTest() { }
}
public class UnitTest_step2
{
public void RunTest() { }
}
public class UnitTest_step3
{
public void RunTest() { }
}
public class UnitTest_step4
{
public void RunTest() { }
}
// End of unit tests
public class IntegrationTests
{
public void IntegrationTest1()
{
UnitTest_step1.RunTest();
UnitTest_step2.RunTest();
UnitTest_step4.RunTest();
}
public void IntegrationTest2()
{
UnitTest_step1.RunTest();
UnitTest_step2.RunTest();
UnitTest_step3.RunTest();
UnitTest_step4.RunTest();
}
public void IntegrationTest3()
{
UnitTest_step1.RunTest();
UnitTest_step4.RunTest();
}
}
[TestClass]
public class SystemTests
{
[TestMethod]
public void Scenario1()
{
IntegrationTests.IntegrationTest1()
}
[TestMethod]
public void Scenario2()
{
IntegrationTests.IntegrationTest2();
}
[TestMethod]
public void Scenario3()
{
IntegrationTests.IntegrationTest3();
}
[TestMethod]
public void ScenarioN()
{
IntegrationTests.IntegrationTestN();
}
}
}
Best Regards.
Well, in my opinion, the information provided in your question is very abstract and the question is a bit too broad.
The answer depends on how your workflow engine is implemented and what are your system requirements.
Requirements and implementation details are what defines your approach to testing.
I would start with clarifying what kind of steps you have, is there any data context is passed,
what side effects these steps produce (writes data to database, sends events, call other system APIs, etc.),
do steps depend on each other and so on.
Another question is how do you need to assert the results, after each step or after scenario?
The system should be testable and normally, each step should be covered with unit tests.
So, suggested hypothetical approach is to cover each step with isolated unit tests
and scenarios with integration tests.
I came up with a simple example just to illustrate one of the general approaches.
For simplicity, I assume that steps have little or no data context and can be reordered.
namespace Workflow.Test
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
[TestClass]
public class SystemTests
{
[TestMethod]
public void Scenario1()
{
new Workflow().Run(new Scenario1());
}
[TestMethod]
public void Scenario2()
{
new Workflow().Run(new Scenario2());
}
// The advantage of explicit steps declaration is test readability.
// Declarative approach also enables the further possibility of test generation!
[TestMethod]
public void MoreExplicitAndDeclarative()
{
new Workflow().Run(new List<Type>
{
typeof(Step1),
typeof(Step2),
typeof(Step3),
});
}
// Step instantiation may be needed if you want to parameterize some steps.
[TestMethod]
[DataRow("Custom step")]
[DataRow("Another step")]
public void MoreExplicitParameterizedScenario(string customName)
{
new Workflow().Run(new List<IRunnable>{
new Step1(),
new Step3(customName)
});
}
}
[TestClass]
public class StepsUnitTests
{
[TestMethod]
public void Step1DoesWhatWeWant()
{
// Mock dependencies
new Step1().Run();
// Assert results
}
}
#region Workflow Engine Example
public interface IRunnable
{
void Run();
}
public class Workflow
{
public void Run(Scenario scenario)
{
Run(CreateSteps(scenario.GetStepTypes()));
}
public void Run(IEnumerable<Type> stepTypes)
{
Run(CreateSteps(stepTypes));
}
public void Run(List<IRunnable> steps)
{
steps.ForEach(step => step.Run());
}
private List<IRunnable> CreateSteps(IEnumerable<Type> stepTypes)
{
var steps = new List<IRunnable>();
foreach (var stepType in stepTypes)
{
steps.Add(CreateStep(stepType));
}
return steps;
}
private IRunnable CreateStep(Type stepType)
=> (IRunnable) Activator.CreateInstance(stepType);
}
#endregion
// Step structure can differ according to system requirements.
// We may add data context and link steps into pipeline if needed.
#region Steps
public abstract class Step : IRunnable
{
private readonly string _stepName;
protected Step(string name)
{
_stepName = name;
}
public void Run()
{
Console.WriteLine($"{_stepName} in action.");
Invoke();
}
public abstract void Invoke();
}
public class Step1 : Step
{
public Step1() : base(nameof(Step1))
{
}
public override void Invoke()
{
// do work
Console.WriteLine($"Step1 invoked.");
}
}
public class Step2 : Step
{
public Step2() : base(nameof(Step2))
{
}
public override void Invoke()
{
// do work
Console.WriteLine($"Step2 invoked.");
}
}
public class Step3 : Step
{
public Step3(string customName) : base(customName)
{
}
public Step3() : this(nameof(Step3))
{
}
public override void Invoke()
{
// do work
Console.WriteLine($"Step3 invoked.");
}
}
public class Step4 : Step
{
public Step4() : base(nameof(Step4))
{
}
public override void Invoke()
{
// do work
Console.WriteLine($"Step4 invoked.");
}
}
#endregion
// Scenarios should be as declarative as possible.
// Let's say the scenario is just specification of what steps (step Type)
// and in what order should be executed (List as a non-unique ordered collection).
#region Scenarios
public abstract class Scenario
{
public abstract List<Type> GetStepTypes();
}
public class Scenario1 : Scenario
{
public override List<Type> GetStepTypes()
=> new List<Type>
{
typeof(Step1),
typeof(Step2),
typeof(Step3)
};
}
public class Scenario2 : Scenario
{
public override List<Type> GetStepTypes()
=> new List<Type>
{
typeof(Step1),
typeof(Step2),
typeof(Step4)
};
}
#endregion
}

How to Use interface IValueEventListener in object DatabaseReference Xamarin.Firebase.Database?

I'm new in C# Xamarin. I have a sample Java class here (from this tutorial). It's difficult to me to implement ValueEventListener in C# using xamarin.firebase.database. Would you like to help me? Thank you.
public class ChatInteractor implements ChatContract.Interactor {
private static final String TAG = "ChatInteractor";
#Override
public void sendMessageToFirebaseUser(final Context context, final Chat chat, final String receiverFirebaseToken) {
final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
databaseReference.child(Constants.ARG_CHAT_ROOMS).getRef().addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void getMessageFromFirebaseUser(String senderUid, String receiverUid) {
final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
databaseReference.child(Constants.ARG_CHAT_ROOMS).getRef().addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
First of all: do you have a Xamarin Android Binding for the Firebase Android SDK? If you don't, you can't really follow any Java-Android tutorial, since the Firebase specific classes / interfaces won't exist. If that's the case: install https://www.nuget.org/packages/Xamarin.Firebase.Database/
If you do - implement the interface like that:
(inline implementations - like you can do in java; and it's done in your example - are not supported in C#. So you'll have to create a regular class)
public class MyValueEventListener : Java.Lang.Object, Firebase.Database.IValueEventListener
{
public void OnCancelled(DatabaseError error)
{
throw new NotImplementedException();
}
public void OnDataChange(DataSnapshot snapshot)
{
throw new NotImplementedException();
}
}
and pass it as an eventlistener
DatabaseReference databaseReference = FirebaseDatabase.Instance.Reference;
databaseReference.Child(Constants.ARG_CHAT_ROOMS).Ref.AddListenerForSingleValueEvent(new MyValueEventListener())

Flag for application started in a framework

I am trying to execute some code in the application start of an HTML Module. Since the Init() gets fired multiple times, is there a reliable flag to tell me if the application started or not?
public class Module : IHttpModule
{
#region IHttpModule Members
public void Dispose()
{
//clean-up code here.
}
public void Init(HttpApplication context)
{
//PROCESS ON APPLICATION START EVENT
this.OnApplicationStart(context);
}
#endregion
public void OnApplicationStart(HttpApplication context)
{
if (!application started??) //FRAMEWORK FLAG?
//DO SOMETHING
}
}
You could use a flag:
public class Module : IHttpModule
{
private static bool isStarted = false;
private static object syncRoot = new object();
public void Dispose()
{
//clean-up code here.
}
public void Init(HttpApplication context)
{
if (!isStarted)
{
lock (syncRoot)
{
if (!isStarted)
{
//PROCESS ON APPLICATION START EVENT
this.OnApplicationStart(context);
isStarted = true;
}
}
}
}
public void OnApplicationStart(HttpApplication context)
{
//DO SOMETHING
}
}
As a better alternative to using HttpModules to perform this task if you are targetting .NET 4.0 or later I would recommend you using WebActivator which is a very handy package based on Microsoft.Web.Infrastructure allowing you to subscribe to events such as Application_Start in separate libraries.
For example, simply put the following code in a class library:
[assembly: WebActivator.PreApplicationStartMethod(typeof(WebAppInitializer), "Start")]
namespace FooBar
{
public static class WebAppInitializer
{
public static void Start()
{
// PROCESS ON APPLICATION START EVENT
}
}
}
and then referencing the class library in your ASP.NET application is all it takes.
You could also use this handy WebActivator to perform dependency injection into your HttpModules and self register them without the need to add them to web.config. Phil Haack wrote a nice blog post on this topic if you are interested.

Categories

Resources